Erben von einem Template
-
Hallo,
ich habe ein Template definiert, das ungefähr so aussieht:
template <class T> class MyTemplate { public: MyTemplate(const UINT zahl); /* ... */ };Jetzt würde ich gerne von diesem Template eine Klasse ableiten. Eigentlich soll da aber keine weitere Funktionalität hinzukommen. Ich benötige eigentlich nur einen Platzhalter:
class MyClass : public MyTemplate<MyType> { };Wenn ich diese Klasse jetzt aber durch
MyClass my( 2 );zu benutzen versuche, bekomme ich die Fehlermeldung
'MyClass::MyClass': function does not take 1 parameterWas habe ich vergessen? Konstruktor für MyClass schreiben? Aber wie gebe ich dann den Parameter zahl an die Basisklasse weiter?
Dankbar für jede Hilfe. Viele Grüße.
-
Indem du die Basisklasse ueber die initialisiererliste initialisierst:
class MyClass : public MyTemplate<MyType> { public: MyClass(const UINT zahl) : MyTemplate<MyType>(zahl) {} }; int main() { MyClass my( 2 ); }Oder indem du das mit dem Ableiten vergisst und einfach einen typedef benutzt (wenn du wirklich nur einen Platzhalter brauchst)
typedef MyTemplate<MyType> MyClass; int main() { MyClass my( 2 ); // gleibedeutend mit MyTemplate<MyClass> my(2); }Das pure Ableiten ohne weiteres das du oben praktiziert hast, gibt folgenden Effekt:
- Da du keinen Konstruktor fuer die neue Klasse angegeben hast, wird ein Defaultkonstruktor generiert, der im Grunde nichts macht als wiederum die Defaultkonstruktoren fuer alle Basisklassen und Memberklassen auzurufen.
- Da aber deine Basisklasse nur der UINT-Konstruktor und keinen Defaultkonstruktor hat, weiss der Compiler nicht, wie er die Basis von MyClass initialisieren soll und gibt dir auf jeden Fall eine Fehlermeldung.
-
mbu schrieb:
Was habe ich vergessen? Konstruktor für MyClass schreiben?
Genau das fehlt.
Aber wie gebe ich dann den Parameter zahl an die Basisklasse weiter?
Über eine Initialisierungsliste:
class MyClass : public MyTemplate<MyType> { public: MyClass(UINT zahl):MyTemplate<MyType>(zahl){} };(btw, das 'const' in der Parameterliste ist unnötig ;))
PS: Wenn du nur einen Platzhalter brauchst, mußt du nichtmal erben -
typedef MyTemplate<MyType> MyClass;reicht meistens aus.
-
Ach natürlich. Ein typedef macht natürlich Sinn. Vielen Dank erstmal für den Tipp.
Hintergrund hierfür ist, dass ich für das Template den << Operator überschrieben habe:
template <class T> std::ostream& operator<<(std::ostream& out, const MyTemplate<T>& my) { /* .. */ }Ich möchte aber für einen bestimmten Typ T eine etwas abgewandelte Ausgabe haben. Jetzt strauchel ich mit dem typedef aber leider über die Redefinition von <<:
typedef MyTemplate<MyType> MyClass; /* .. */ std::ostream& operator<<(std::ostream& out, const MyClass& myc) { /* .. */ }Führt nämlich leider zu einem Linkerfehler.
LNK2005: ... already defined in class.obj
LNK1169: ... one or more multiply defines symbols foundGeht das Überschreiben des << Operators so nicht?
-
Hat sich inzwischen erledigt. Ich habe es hinbekommen. Das Linkerproblem bestand nur in meiner Aufteilung von .h und .cpp Dateien. Bin da etwas durcheinander gekommen.
Vielen Dank trotzdem für die schnelle Hilfe!!
Gruss. mbu.
-
Du kannst auch - voellig ohne typedef und Ableitung - das Funktionstemplate vollstaendig spezialisieren.
template <class T> std::ostream& operator<<(std::ostream& out, const MyTemplate<T>& my);ist ein Funktionstemplate und gleichzeitig eine Ueberladung der bereits bestehenden Funktionen mit Namen operator<<
Deine zweite Definition ist eine weitere Ueberladung des Operatoers, statt dessen kannst du auch das bereits bestehende Template spezialisieren, da die Ausgabe von MyTemplate<MyType> ja tatsaechlich auch ein SPezialfall dieses Templates ist:
template<> std::ostream operator<< <MyType> (std::ostream& out, const MyTemplate<MyType>& my);Das <MyType> hinter operator<< kann in diesem Fall auch weggelassen werden, da der Compiler in der Lage ist, den Templateparameter aus den Funktionsargumenten abzuleiten. Ich hab keine Ahnung ob template-Spezialisierung in schnellerem Code resultiert als die Operator-Ueberladung, allerdings drueckt sie die Zugehoerigkeit zum template inmeinen Augen besser aus als eine weitere Operatorueberladung - pure aesthetik also
