PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C++: Funktionspointer für Klassen


Gast
2008-02-18, 08:44:55
hallo

ich möchte in einer Fabrik Instanzen von verschiedenen Klassen erstellen, die Klassen sind alle Kindklassen eines abstrakten Typs, die konkreten Implementationen sollen aber bei der Fabrik zur Laufzeit registriert werden. Allerdings habe ich es nicht hinbekommen Funktionspointer auf Konstruktoren abzubilden (bzw. das scheint auch nicht zu gehen, oder?) - wie könnte ich diese Klassen denn in einer Liste o.ä. registrieren und bei Bedarf eine Instanz dieser erstellen; wenn die Implementation der Fabrik den Klassentyp nicht kennt bzw. kennen soll?

danke

pest
2008-02-18, 09:00:40
hallo

ich möchte in einer Fabrik Instanzen von verschiedenen Klassen erstellen, die Klassen sind alle Kindklassen eines abstrakten Typs, die konkreten Implementationen sollen aber bei der Fabrik zur Laufzeit registriert werden. Allerdings habe ich es nicht hinbekommen Funktionspointer auf Konstruktoren abzubilden (bzw. das scheint auch nicht zu gehen, oder?) - wie könnte ich diese Klassen denn in einer Liste o.ä. registrieren und bei Bedarf eine Instanz dieser erstellen; wenn die Implementation der Fabrik den Klassentyp nicht kennt bzw. kennen soll?

danke

Die überladenen Funktionen der Vaterklasse als virtual deklarieren.


class Auto {
public:
Auto(){anz_raeder=0;};
virtual void SetRaeder()=0;
~Auto(){};
protected:
int anz_raeder;
};

class BWM : public Auto {
BWM();
~BWM();
void SetRaeder(){anz_raeder=4;};
}


dann ne Liste die aus Pointern auf "Auto" bestehen.
und mit einer abgeleiteten Klasse initalisieren.


Auto *Test=new BWM();

Ectoplasma
2008-02-18, 09:10:48
Ist die Signatur des CTORs der Implementierungsklassen, die du erzeugen möchtest, immer gleich? Außerdem gibt es immer wieder kleine Meinungsverschiedenheiten, was eine Fabrik macht.

Ich hätte da folgenden Vorschlag. Du hast eine abstrakte Fabrikklasse. Die sieht z.B. so aus:


class Factory {
public:

virtual ~Factory() {}
virtual ObjectToCreate *create() = 0;
};



Jetzt genauer. Jede Fabrikklasse produziert genau einen Klassentyp. Man kann sich das vereinfachen mit einer Templateklasse:


template < class __Type >
class FactoryT : public Factory
{
public:

ObjectToCreate *create() {
return new __Type; // default CTOR wird verwendet
}
};


Man braucht jetzt noch einen Container, der Fabrikinstanzen aufnimmt. Das macht man z.B. mit einer map. Der Key kann z.B. ein String sein.

typedef std::map<std::string, Factory*> MyFactoryRegistry;

Und nun kann man das Teil befüllen.


MyFactoryRegistry factoryRegistry;

factoryRegistry.insert(MyFactoryRegistry::value_type("type1", new FactoryT<Type1>()));
factoryRegistry.insert(MyFactoryRegistry::value_type("type2", new FactoryT<Type2>()));

usw.


Konkrete Instanzen werden dann so erzeugt:



// erzeuge Objekt

MyFactoryRegistry::iterator it = factoryRegistry.find("type1");
ObjectToCreate *pObject = NULL;

if (it != factoryRegistry.end()) {
pObject = (*it).second->create();
} // if

...



Jetzt kann man noch alles schön in Funktionen oder in eine eigene Klasse verpacken. Ist jetzt nur ein Vorschlag. Ich hoffe die Idee ist rübergekommen.

ethrandil
2008-02-18, 12:19:51
Hallo,
ich möchte in einer Fabrik Instanzen von verschiedenen Klassen erstellen, die Klassen sind alle Kindklassen eines abstrakten Typs, die konkreten Implementationen sollen aber bei der Fabrik zur Laufzeit registriert werden.
die vorgestellten Methoden funktionieren, wenn zur Kompilierzeit schon alle Klassen bekannt sind. Wenn Code dynamisch nachgeladen werden soll, geht das nicht so einfach. Ist das bei dir der Fall?

mfg
- eth

Gast
2008-02-18, 12:51:01
Hallo,

die vorgestellten Methoden funktionieren, wenn zur Kompilierzeit schon alle Klassen bekannt sind. Wenn Code dynamisch nachgeladen werden soll, geht das nicht so einfach. Ist das bei dir der Fall?

mfg
- eth

Doch schon. Wenn du z.B. eine DLL nachlädst, dann liefert die DLL selbst die enstprechende Factory. Diese ist dann wie oben von der abstrakten Factory abgeleitet. D.h. die Implementierung muss nicht zur Compile-Time der Hauptanwendung bekannt sein.

Ectoplasma
2008-02-18, 12:52:27
Doch schon. Wenn du z.B. eine DLL nachlädst, dann liefert die DLL selbst die enstprechende Factory. Diese ist dann wie oben von der abstrakten Factory abgeleitet. D.h. die Implementierung muss nicht zur Compile-Time der Hauptanwendung bekannt sein.

Sorry, hatte vergessen mich anzumelden. Der Gast-Post über mir war ich.

Gast
2008-02-19, 08:23:54
Danke an alle.

@Ectoplasma das scheint ziemlich genau zu sein, an was ich gedacht habe -- muß zwar nochmal schauen, wie ich einige Details für mich umsetzen kann, aber das geht definitiv in die richtige Richtung. Danke :)