std::vector von zeigern auf methoden abgeleiteter klassen in basisklasse definieren
-
Hallo,
ich bin relativ neu hier und bringe gleich mal ein gewichtiges problem mit

ich wollte eine struktur haben, mit der ich abgeleiteten klassen erlauben kann, methoden zu registrieren (in einen vector zu pushen, der in der basisklasse definiert ist) und danach mit der basisklasse diese registrierten methoden strukturiert aufrufen möchte. der intergrund dabei ist, dass für die methoden der abgeleiteten klassen viel ähnliches passiert, was ich nicht in jede abgeleitete klasse hineincoden, sondern im der basisklasse kapseln möchte.
so, methodenzeiger an sich sind ja kein problem. die schwierigkeit ist eher, dass die methoden der abgeleiteten klassen, sowie die der basisklasse, zwar gleiche definitionen, aber durch die verschiedene klassenzugehörigkeit unterschiedliche signaturen aufweisen.
z.b.bool(Base::*)()ist nicht gleich
bool(Derived::*)()falls noch mehr informationen benötigt werden um das problem zu lösen, lasst mich das bitte wissen

ansonsten hoffe ich auf kreative vorschlägeviele grüße,
AndiEDIT: okay, problem wurde durch casts gelöst.
(bool(Base::*)())&Derived::method()
-
Das Problem hört sich für mich nach einer Problemstellung für ein NVI an.
Ungetestet schrieb:
class Base { public: void DoTheMagic() { // code gleich für jede klasse DoTheSpecial(); // code gleich für jede Klasse } private: virtual void DoTheSpecial() { // Standard Implementierung } }; class Derived : public Base { private: virtual void DoTheSpecial() { // Derived Impl; } }; int main() { Derived d; d.DoTheMagic(); }Edit: Nachzulesen auch in Effective C++ Tipp 35
-
ja, an sowas hatte ich auch gedacht. leider ermöglicht das nicht komplett die funktionalität die ich brauchte, da eine abgeleitete klasse potentiell beliebig viele methoden der form DoTheSpecial haben kann, wobei diese anzahl in den abgeleiteten klassen variiert.
EDIT: aber wie gesagt, problem ist bereits gelöst

-
hier ist mal, vereinfacht, der code wie er jetzt läuft. ich hoffe damit wirds etwas klarer

class Base { public: Base() : _registeredMethods(std::vector<bool (Base::*)()>()) {}; virtual ~Base(); void run() { registerMethods(); std::vector<bool (Base::*)()>::iterator i = _registeredMethods.begin(); for(;i != _registeredMethods.end(); i++) { if((*this.*(*i))()) std::cout << "ok" << std::endl; else std::cout << "phail" << std::endl; } } protected: virtual registerMethod() = 0; std::vector<bool(Base::*)()> _registeredMethods; } class Derived : public Base { public: Derived(); ~Derived(); private: void registerMethods() { _registeredMethods.push_back((bool (Base::*)())&Derived::foo); _registeredMethods.push_back((bool (Base::*)())&Derived::bar); } bool foo() { return true; } bool bar() { return false; } } // some more derived classes follow int main() { std::vector<Base*> classes = std::vector<Base*>() classes.push_back(new Derived()) // some more pointers to other derived classes are pushed back std::vector<Base*>::iterator i = classes.begin(); for(;i != classes.end(); ++i) { (*i)->run(); } }
-
Wie wärs mit
functionundbind?#include <functional> #include <vector> class base { public: typedef std::tr1::function<bool ()> callback_type; virtual ~base(){} void run() { typedef callback_list_type::const_iterator iter_type; for(iter_type i(callback_list.begin()), end(callback_list.end()), i != end; ++i) { if((*i)()) { std::cout << "Result A" << std::endl; } else { std::cout << "Result B" << std::endl; } } } protected: void register_callback(callback_type const & cb) { callback_list.push_back(cb); } private: typedef std::vector<callback_type> callback_list_type; callback_list_type callback_list; }; class derived : public base { public: derived() { this->register_callback(std::tr1::bind(&derived::foo, this)); this->register_callback(std::tr1::bind(&derived::bar, this)); } private: bool foo() { return true; } bool bar() { return false; } }; int main() { std::vector<base*> classes; classes.push_back(new derived()) // some more pointers to other derived classes are pushed back std::vector<base*>::iterator i = classes.begin(); for(;i != classes.end(); ++i) { (*i)->run(); } }
-
Ich seh da noch keinen Vorteil gegenüber:
class Base { public: virtual ~Base(){} void run() { pre(); if (!do_run()) cout << "fail"; post(); } private: void pre(); void post(); virtual bool do_run() = 0; }; class Derived : public Base { private: bool do_run() { return foo() && bar(); } bool foo() { return true; } bool bar() { return false; } };
-
perfect. that's exactly what I was looking for

thanks a lotEDIT: irks... -.- ich sollte aufhören englische und deutsch foren parallel zu lesen
-
@Taychon:
ist std::tr1 teil des C++0x standards?
-
AndiCpp schrieb:
@Taychon:
ist std::tr1 teil des C++0x standards?
Jein. Der TR1 ist ein Entwurf für eine Biblithekserweiterung, die 2003 veröffentlicht wurde. Die meisten gängigen Compiler haben das implementiert. Das meiste vom TR1 wird so oder so ähnlich in den 0x-Standard übernommen.
-
ah, oaky. ich hab mich nämlich grad darüber gewundert:
error: 'tr1' is not a member of 'std'