Objektorientierte Rückrufe für C ++?

8

Gibt es eine Bibliothek, die es mir erlaubt, objektorientierte Rückrufe in C ++ einfach und bequem zu erstellen?

Die Sprache Eiffel zum Beispiel hat das Konzept von "Agenten", die mehr oder weniger so funktionieren:

%Vor%

Ausgabe wird sein: Hallo von Bar! 3 Hallo von Foo!

Also - der Agent erlaubt es, eine Memberfunktion in ein Objekt zu kapseln, sie entlang einiger vordefinierter Aufrufparameter (Hi from Foo) zu übergeben, die offenen Parameter (?) anzugeben und sie an ein anderes Objekt zu übergeben, das sie dann aufrufen kann später.

Da c ++ es nicht erlaubt, Funktionszeiger auf nicht-statischen Elementfunktionen zu erstellen, scheint es nicht so trivial zu sein, etwas so einfach in c ++ zu implementieren. Ich fand einige Artikel mit Google auf objektorientierten Callbacks in C ++, aber tatsächlich suche ich nach Bibliotheken oder Header-Dateien, die ich einfach importieren kann, die mir erlauben, eine ähnlich elegante Syntax zu verwenden.

Hat jemand ein paar Tipps für mich?

Danke!

    
Mat 19.08.2010, 08:52
quelle

7 Antworten

10

Die einfachste Art, Callbacks in C ++ zu verwenden, besteht darin, eine Funktion einer Schnittstelle aufzurufen und dann eine Implementierung dieser Schnittstelle zu übergeben.

%Vor%     
stefaanv 19.08.2010 10:01
quelle
5

Menschen verwenden normalerweise eines von mehreren Mustern:

Vererbung. Das heißt, Sie definieren eine abstrakte Klasse, die den Callback enthält. Dann nimmst du einen Zeiger / Verweis darauf. Das bedeutet, dass jeder diesen Callback erben und bereitstellen kann.

%Vor%

Vererbung erneut. Das heißt, Ihre Stammklasse ist abstrakt, und der Benutzer erbt davon und definiert die Callbacks, anstatt eine konkrete Klasse und dedizierte Callback-Objekte zu haben.

%Vor%

Noch mehr Vererbung - statisch. Auf diese Weise können Sie Vorlagen verwenden, um das Verhalten eines Objekts zu ändern. Es ähnelt der zweiten Option, funktioniert aber zur Kompilierungszeit statt zur Laufzeit, was je nach Kontext zu verschiedenen Vor- und Nachteilen führen kann.

%Vor%

Sie können Memberfunktionszeiger oder normale Funktionszeiger verwenden und verwenden

%Vor%

Es gibt Funktionsobjekte - sie überladen den Operator (). Sie werden einen funktionalen Wrapper verwenden oder schreiben wollen, der zur Zeit in der std :: / boost :: -Funktion zur Verfügung gestellt wird, aber ich werde hier auch einen einfachen zeigen. Es ähnelt dem ersten Konzept, verbirgt aber die Implementierung und akzeptiert eine Vielzahl anderer Lösungen. Ich persönlich benutze das normalerweise als meine Rückrufmethode der Wahl.

%Vor%

Die richtige Lösung hängt hauptsächlich vom Kontext ab. Wenn Sie eine C-style-API bereitstellen müssen, dann ist Funktionszeiger der einzige Weg zu gehen (erinnern Sie sich an void * für Benutzerargumente). Wenn Sie zur Laufzeit variieren müssen (z. B. wenn Sie Code in einer vorkompilierten Bibliothek verfügbar machen), kann die statische Vererbung hier nicht verwendet werden.

Nur eine kurze Anmerkung: Ich habe den Code ausgepackt, damit er nicht perfekt ist (wie Zugriffsmodifizierer für Funktionen usw.) und möglicherweise ein paar Bugs enthält. Es ist ein Beispiel.

    
Puppy 19.08.2010 14:36
quelle
3

Wie wäre es mit Funktor

?     
dubnde 19.08.2010 09:32
quelle
2

C ++ erlaubt Funktionszeiger auf Member-Objekten.
Weitere Details finden Sie hier .
Sie können auch boost.signals oder boost.signals2 (abhängig davon, ob Ihr Programm Multithread ist oder nicht).

    
the_drow 19.08.2010 09:00
quelle
1

Es gibt verschiedene Bibliotheken, mit denen Sie das tun können. Schau dir boost :: function an.

Oder versuchen Sie Ihre eigene einfache Implementierung:

%Vor%

Verwendung:

%Vor%     
Grozz 19.08.2010 10:43
quelle
1

Verknüpfen Sie die Idee von Funktoren - verwenden Sie std :: tr1 :: function und boost :: bind, um die Argumente vor dem Registrieren zu erstellen.

    
rkellerm 19.08.2010 11:15
quelle
0

Es gibt viele Möglichkeiten in C ++, wobei das Problem im Allgemeinen eine Syntax ist.

  • Sie können Zeiger auf Funktionen verwenden, wenn Sie keinen Zustand benötigen, aber die Syntax ist wirklich schrecklich. Dies kann mit boost::bind für eine noch mehr ... interessante ... Syntax (*)
  • kombiniert werden
  • Ich korrigiere deine falsche Annahme, es ist in der Tat machbar, Zeiger auf eine Elementfunktion zu haben, die Syntax ist einfach so peinlich, dass du wegläufst (*)
  • Sie können Functor-Objekte verwenden, im Grunde ist ein Functor ein Objekt, das den Operator () überlädt, zum Beispiel void Functor::operator()(int a) const; , weil es ein Objekt ist, das es angibt und von einer gemeinsamen Schnittstelle ableiten kann
  • Sie können einfach Ihre eigene Hierarchie mit einem schöneren Namen für die Callback-Funktion erstellen, wenn Sie nicht möchten, dass der Benutzer die Straße überlastet.
  • Schließlich können Sie die Vorteile von C ++ 0x nutzen: std::function + Die Lambda-Funktionen sind wirklich großartig, wenn es um Ausdruckskraft geht.

Ich würde mich über eine Überprüfung der Lambda-Syntax freuen;)

%Vor%

Natürlich ist func nur lebensfähig, während foo realisierbar ist (Scope-Problem). Sie könnten foo kopieren, indem Sie [=foo] verwenden, um den Wert als Wert anzugeben, statt als Referenz.

(*) Obligatorisches Tutorial zu Funktionszeigern

    
Matthieu M. 19.08.2010 14:27
quelle