2009-03-23 13 views
2

Ich möchte den Zeiger auf das Objekt und eine Angabe, welche Methode der Funktor von einem Funktor aufgerufen wird mit boost :: function aufrufen und boost :: bind. Dies wird mir erlauben, automatisch die Reihenfolge in einer Reihe von Funktoren zu bestimmen.Bestimmen Sie Objekt und Methode in einem Funktor mit boost :: function und boost :: bind

Der folgende (Pseudo-) Code (siehe POINTER_OF & METHOD_OF) zeigt, was ich versuche zu tun:

class myClassA 
{ 
    public: 
    DoIt(int i) { return i+i; } 
}; 

class myClassB 
{ 
    public: 
    DoItToo(double d) { return d*d; } 
}; 

typedef boost::function0<int> Functor; 

myClassA classA; 
myClassB classB; 

Functor funcA = boost::bind(&myClassA::DoIt, &classA, 10); 
Functor funcB = boost::bind(&myClassB::DoItToo, &classB, 12.34); 

// Create a vector containing some functors and try to determine the objects 
// they are called upon and the methods they invoke 
std::vector<Functor> vec; 
vec.push_back(funcA); 
vec.push_back(funcB); 

for (int i = 0; i < vec.size();i++) 
{ 
    if (POINTER_OF(vec[i]) == &classA) 
    { 
    // This functor acts on classA 
    if (METHOD_OF(vec[i]) == &myClassA::DoIt) 
    { 
     // This functor calls the 'DoIt' method. 
    } 
    else if (METHOD_OF(vec[i]) == &myClassB::DoItToo) 
    { 
     // This functor calls the 'DoItToo' method. 
    } 
    } 
    // etc... 
} 

Vielen Dank im Voraus!

+0

Code, was Sie wnat schreiben sieht hässlich aus. Es tut uns leid. Bitte geben Sie zusätzliche Informationen an, was Sie mit Informationen über Zeiger und Methode machen möchten. – bayda

+0

einige Stil Beratung, umbenennen "KlasseA" - es ist keine Klasse, es ist ein Objekt, das eine Instanz einer bestimmten Klasse ist. "instanceA" wäre in Ordnung; "instanceOfClassA" ist besonders ausführlich, würde aber zumindest genau sein. – Aaron

Antwort

4

Ich weiß, dass das folgende ist keine strenge Antwort auf Ihre Frage, aber.

Tun Sie dies nicht. Verwenden Sie stattdessen Polymorphie. Es ist eines der merkwürdigsten Dinge, die ich in meinem aktuellen Projektcode sah: Wenn der Funktionszeiger auf "someFunction" zeigt - machen Sie ein paar zusätzliche Aktionen.

Sie können zusätzliches Verhalten hinzufügen, ohne Ihre Klassen viel mit Decorator Entwurfsmuster zu ändern. Das wird deine myClassA :: DoIt mit Decorator :: DoIt erweitern. Keine

http://en.wikipedia.org/wiki/Decorator_pattern

+0

Vielleicht ist mein Beispiel nicht klar ;-) Ich muss nur das Objekt und die Methode ermitteln, die für eine große Liste von Funktoren aufgerufen werden, um die Ausführungsreihenfolge der Methoden zu bestimmen, da sie alle Nebenwirkungen haben und aufeinander angewiesen sind (used in der Maschinensteuerung - Objekte repräsentieren physikalische Systeme) –

+0

@lasser - das ändert nichts an der guten Meinung von Mykola's Antwort. Sie benötigen eine Liste von Objekten, die eine Priorität und eine Funktion haben. –

0

, ich glaube nicht, können Sie das Ziel einer Boost-Funktion erhalten, die zu einer Erhöhung bindet gesetzt ist (dh METHOD_OF). Laut this post auf der Boost-Mailing-Liste ist dies, weil der Rückgabetyp der Bindung nicht formal angegeben ist.

Edit: Link zu einer früheren Frage, die einige-was im Zusammenhang mit dieser Frage: demote-boostfunction-to-a-plain-function-pointer

0

boost::function Objekte sind Gleichheit vergleichbar, so sollten Sie in der Lage sein, Dinge zu tun wie

if (vec[i] == boost::bind(&myClassA::DoIt, &classA, 10)) 
{ 
    // ... this Functor calls DoIt on classA with argument 10 
} 

Ich vermute Sie suchen nach etwas allgemeinerem jedoch. Ein genauerer Blick auf die Implementierungsdetails von boost/function_equal.hpp (dh boost::bind 's function_equal_impl) könnte Ihnen eine Idee geben, wie Sie selektiv eine Teilmenge der Argumente boost::bind testen können.

Aber ich denke wirklich, dass Sie besser mit einer Polymorphismus-basierten Lösung oder nur aggregieren die Funktionsobjekte mit einigen Metadaten.

+0

Danke für deinen Kommentar, timday. Wenn ich richtig verstehe, wenn ich equal_impl benutze, werde ich immer noch das Problem haben, das Objekt und die Methode aus boost :: bind herauszuholen ... Vergleiche boost :: bind Instanzen funktionieren auch nicht, da sie unterschiedlich sind wenn verschiedene Parameter übergeben werden . –

+0

Die Implementierung des Gleichheitstests selbst muss Zugriff auf das Objekt und die Methode haben (um sie zu vergleichen), weshalb ich schlage vor, wie diese implementiert werden. – timday

Verwandte Themen