Klasse an Funktion übergeben. Und auch wieder zurück.
-
mir viel grad was ein, die idee ist noch nicht ausgereift und ich hab keine ahnung ob das überhaupt umsetzbar ist, aber vielleicht könnt ihr damit weiterarbeiten, dies ist nur eine art pseudocode:
class base{}; template<class T> struct derived:public base{ typedef T valueType; }; template<class T>void registerClass(std::string a){ map.insert(pair<base*,std::string>(new derived<T>,a); } void execute( std::string b){ *(map.find(b)->second)::valueType::static_func(); }
-
Ich weiss zwar nicht, was das soll, aber falls du den Thread gelesen hättest, wüsstest du, dass das alles schon hier steht ...
-
war halt nur ein lösungsansatz um an den klassentyp selber zu kommen, bisher wurde das ja eher über funktionen versucht, mein lösungansatz ging über typedefs(und der ansatz wurde hier noch nicht genannt
)
-
Und was ist das dann?
0xdeadbeef schrieb:
Whoops, passt wohl doch besser in diesen Thread. Ich hab da mal was geschrieben, was dich interessieren könnte: http://www.dev-geeks.org/forum/viewtopic.php?t=110
Die Technik, die ich da benutze, basiert auf einer Art Metafunktion. Ich hab eine Hilfsklasse
struct basic_factory_helper { virtual value_type *create_instance() = 0; };
...und eine davon abgeleitete template, die ich für jede Klasse, die die Factory verwalten soll, konkretisiere:
template<typename _t> struct factory_helper : basic_factory_helper { virtual value_type *create_instance() { return pointer(new _t()); } };
...wobei value_type ein Parameter der factory, die sinnigerweise auch templatisiert ist, und pointer ein value_type* ist. Auf diese Art kann ich nachher in einer std::map<key_type, basic_factory_helper*> factory_helpers für alle registrierten Klassen speichern und bei Bedarf darauf zugreifen. Die Registrierung geht dann über die template-Methode
template<typename _t_reg> void register_class(key_type const &k);
...also z.B. mit
factory<std::string, Base>::register_class<Derived>("Derived");
Der restliche Code wrappt dieses Prinzip in ein Singleton und stellt ein paar convenience-Funktionen zur Verfügung, damit man nicht immer factory<key, value>::instance().create("foo"); schreiben muss...
Beiträge sind übrigens nicht so böse gemeint, wie sie sich anhören
-
Und was ist das dann?
ein anderer ansatz mit ähnlichem interface und einer instanz der klasse, mit dem zwangsläufigen nachteil, dass man keine statischen funktionen von den gespeicherten klassen aufrufen kann?
aber was weis ich schon^^
//edit böser rechtschreibfehler kusch, verschwinde
-
Die Instanz gibt's aber erst, wenn man ein create_instance aufruft.
Wenn man die factory_helper_base und die factory_helper ein wenig abändert, kann man auch ohne probleme statische Funktionen aufrufen:struct basic_factory_helper { virtual value_type *create_instance() = 0; virtual void execute()=0; };
template<typename _t> struct factory_helper : basic_factory_helper { virtual value_type *create_instance() { return pointer(new _t()); } virtual void execute() { _t::static_function(); } };
void execute( std::string b){ map.find(b)->second->execute(); }
Aber ich hab mir deins grad erst richtig angeschaut, muss mal prüfen, ob das net doch was anderes ist
-
@otze: Das mit den typedefs wird nicht hinhauen, weil die bereits zur Compilezeit aufgelöst werden.
@deUS: Hm. OK, das kann man so machen. Allerdings ist die factory dann auf Klassen beschränkt, die die entsprechenden statischen Funktionen mitliefern. Für meinen Geschmack nicht sonderlich schön, aber über Geschmack kann man bekanntlich lange und ergebnislos streiten. Funktionieren sollte es allemal.
-
Jo, sowas würde ich auch nicht implementieren. Die schönste Möglichkeit wäre es wohl einfach eine instanz auf die struct derived von otze zurückzugeben, dann könnte man beliebige statische funktionen aufrufen, so wie er es in seinem beispiel auch macht, nur eben ausserhalb der klasse.
-
die frage ist nur, wie man an den value_type kommen sollte, immerhin kann man ja von base nicht auf derived casten ohne den template parameter mitzugeben, und einen value_type in base kann man soweit ich weis nicht überschreiben...
wäre intressant, mal deine implementation zu sehen, falls dus schaffen solltest
-
#include <iostream> struct A { static void foo() { std::cout << 'A' << std::endl; } }; struct B : public A { static void foo() { std::cout << 'B' << std::endl; } }; int main() { A *p = new B; p->foo(); delete p; }
Ausgabe:
A
statische Funktionsaufrufe werden zur Compilezeit aufgelöst. Auf die Art kommt ihr nicht weiter.
-
@otze:
Oha, da hab ich garnicht dran gedacht ... Mist
-
da die templateparameter ja eh zur compilezeit ausgewertet werden, und wir darum nichts dynamisches damit zustande bringen könnten,könnten wir das dann nicht alternativ auf einer typliste basieren lassen?
//pseudocode class A{}; class B{}; class C{}; typedef typelist<A,B,C> myClasses; //irgendwo in irgendeiner klasse/funktion getType<myClasses,2>::value_type::static_func();
-
Das kannst du meinetwegen machen, aber es ist bei weitem nicht so mächtig wie eine factory. Es bringt nur dann was, wenn du vorher alle Klassen kennst, die die Factory rausschmeißen soll, und bringt dir also z.B. für Plugin-Architekturen aller Art so rein gar nichts.