Klassenunabhängige Methodenzeiger
-
Hallo,
weiß jemand, warum C++ keine klassenunabhängigen Methodenzeiger (Closures in Borland C++) unterstützt?
Vielen Dank im Voraus!
Moritz
-
Warum bruahct man die?
-
Die Methodenzeiger verschiedener Klassen unterscheiden sich in der Signatur (als erstes Argument wird ein Pointer auf ein Objekt der Klasse übergeben - this). Dementsprechend sind es unterschiedliche Datentypen, und da C++ typesafe ist...
Was die Borland-closures angeht, wenn ich das richtig sehe, ist das auch nur ein Methodenzeiger auf eine Methode von TObject, von der der Rest der VCL ableitet.
-
__closure (oder so ähnlich) ist eine inoffizielle Erweiterung einiger Kompilerhersteller...
-
0xdeadbeef schrieb:
Die Methodenzeiger verschiedener Klassen unterscheiden sich in der Signatur (als erstes Argument wird ein Pointer auf ein Objekt der Klasse übergeben - this). Dementsprechend sind es unterschiedliche Datentypen, und da C++ typesafe ist...
Hm, sind Borland-closures nicht sowas wie Delegates in .net? Falls das so ist (falls nicht, das Folgende bitte ignorieren), dann trifft der Ausdruck "klassenunabhängige Methodenzeiger" ja nicht im geringsten zu, treffender wäre "gebundener Methodenzeiger". Also das, was bei (obj.*method) herauskommt, bevor man den () Operator anwendet. Warum es das nicht gibt, ist eine gute Frage, und hat mit Sicherheit nichts mit Typsicherheit zu tun.
-
Es ist zwar in der Tat schade, dass C++ sowas von sich aus nicht bietet, aber zumindest lässt sich das ja recht einfach selbst bauen.
Siehe: boost::function (plus boost::bind) und boost::signal.
-
0xdeadbeef schrieb:
Was die Borland-closures angeht, wenn ich das richtig sehe, ist das auch nur ein Methodenzeiger auf eine Methode von TObject, von der der Rest der VCL ableitet.
Nicht ganz, denn Methodenzeiger lassen sich auch nicht auf abgeleitete Klassen anwenden, zumindest nicht nach Standard-Spezifikation. Außerdem sind die Closures auf jede Klasse anwendbar. Sie enthalten sowohl die Funktionsadresse als auch die Adresse des zugehörigen Objekts und lassen sich dann wie Funktionszeiger verwenden. Borlands VCL braucht sie als Zeiger auf Ereignis-Handler-Funktionen (die aufgerufen werden, wenn z.B. ein Button angeklickt wird).
Closures funktionieren etwa so:
#include <iostream> class class1 { public: void foo (int arg); }; void class1::foo (int arg) { std::cout << "class1::foo (" << arg << ")" << std::endl; } class class2 { public: void foo2 (int arg); }; void class2::foo2 (int arg) { std::cout << "class2::foo2 (" << arg << ")" << std::endl; } int main (void) { void (__closure* cls) (int); class1 c1; class2 c2; cls = c1.foo; cls (1); // gibt "class1::foo (1)" aus cls = c2.foo2; cls (2); // gibt "class2::foo2 (2)" aus }