Template Klasse als Argument in einem Konstruktor (einer anderen Klasse)
-
Hallo!
habe eine template klasse geschrieben:
template<class T> class Klasse1 { public: Klasse1(int x, int y, int z, T *mem); virtual ~Klasse()1; private: ... };
Jetzt habe ich eine andere Klasse, die im Konstruktor ein Argument der template Klasse hat:
class Klasse2 { public: template <typename T> Klasse2(Klasse1<T> *argKlasse1); }; in der cpp: template <typename T> Klasse2::Klasse2(Klasse1<T> *argKlasse1) { }
objekte von der template klasse erzeugen und benutzen geht.
sobald ich aber ein objekt von Klasse2 anlege, gibt es einen linker fehler. (nicht aufgeloestes externes symbol), liegt also irgendwie an der syntax!?!
kann mir jemand weiterhelfen?
gruss
-
egger schrieb:
kann mir jemand weiterhelfen?
Ja
Du kannst eine Template-Definition nicht in eine eigene C++-Datei packen, sonst kann der Compiler die entsprechende Funktion nicht erstellen (weil dafür benötigt er außer den Definitionen auch noch die Information, für welchen Datentyp "T" stehen soll) - und ohne konkrete Funktion macht der Linker Probleme.
-
ich dachte, dass waere gerade der vorteil von templates, dass der datentyp vorher nicht bekannt sein muss.
ausserdem habe ich den konstruktor der klasse2 doch als template methode definiert, also sollte es doch klappen !?!
-
egger schrieb:
ich dachte, dass waere gerade der vorteil von templates, dass der datentyp vorher nicht bekannt sein muss.
Wenn du die Template-Klasse entwickelst, ist der verwendete Datentyp egal (du gehst einfach davon aus, daß er alle benötigten Operationen anbietet). Wenn du die Template-Klasse anwendest, brauchst du einen bestimmten Datentyp.
ausserdem habe ich den konstruktor der klasse2 doch als template methode definiert, also sollte es doch klappen !?!
Ja, hast du - und genau das ist dein Problem
Wenn der Compiler deinen Anwendungscode anfässt, sieht er nur die Deklarationen und notiert dem Linker, daß er z.B. einen Konstruktor "Klasse2::Klasse2(Klasse1<int>)" benötigt.
Wenn der Compiler die "klasse2.cpp" bearbeitet, hat er keine Ahnung, ob er später den Konstruktor "Klasse2::Klasse2(Klasse1<int>)", "Klasse2::Klasse2(Klasse1std::string*)" oder irgendwas anderes benötigen wird - also kann er keinen brauchbaren Code zusammensetzen (eine Anweisung wie "T tmp =arg->data();" sieht zwar für jeden Typ gleich aus, resultiert aber in völlig anderen Maschinencodes.Als Lösung deines Problems bleibt dir nur eine Möglichkeit: Schieb die Definition des Konstruktors aus der CPP-Datei in den Header.