Basisklasse als Templateparameter übergeben (sinnvoll???)
-
Ok, danke.
Und kannst du was mit dem Linker-Error anfangen?
"undefined reference to" und dann folgt der Konstruktor meiner Klasse, also z.B.
Klasse<Kaempfer>::Klasse()Aber halt nur manchmal.
Deswegen steige ich da auch nicht durch...
Edit:
Ich füge nochmal den Code an.
Aber an dem kann's ja eigentlich nicht liegen, wenn's mal geht und mal nicht...// klasse.h #include <iostream> #include <string> #include "char.h" #include "kaempfer.h" #ifndef _KLASSE_H_ #define _KLASSE_H_ template <class T> class Klasse : public T, public Char { public: Klasse(); }; #endif// klasse.cpp #include <iostream> #include "klasse.h" #include "char.h" template <class T> Klasse<T>::Klasse():Kaempfer() { name = "Sinthoras"; iTW = 1; };// main.cpp (...) Klasse<Kaempfer> NSC; (...)Manchmal klappt es halt...
Eben auch als ich die Zeile "Klasse<Kaempfer> NSC;" auskommentiert habe (es scheint also wirklich am Konstruktor zu liegen) und seltsamerweise auch, als ich "klasse.cpp" (mit dem Konstruktor) als Test per #include in main eingebunden habe. Soll man ja nich machen.Edit2: Also irgendwie habe ich das Gefühl, er peilt nicht, dass die Konstruktor zu Klasse nicht in klasse.h sondern in klasse.cpp ist.
Aber die Dateien sind hübsch alle in einem Projekt und manchmal gehts ja irgendwie...
-
Bei templates müssen Funktionsprototyp und Implementation in der selben Einheit sein.
// klasse.h #include <iostream> #include <string> #include "char.h" #include "kaempfer.h" #ifndef _KLASSE_H_ #define _KLASSE_H_ // template <class T> class Klasse : public T, public Char { public: Klasse(); }; #include "klasse.cpp" //hier so #endif// klasse.cpp #include <iostream> //#include "klasse.h" und das weg #include "char.h" template <class T> Klasse<T>::Klasse():Kaempfer() { name = "Sinthoras"; iTW = 1; };oder gleich alles in den header
-
Ok, danke, vielen Dank, euch allen.
Edit:
Hm, wenn ich es so einbinde, bekomme ich dann folgende Meldungen:expected constructor, destructor, or type conversion before '<' token
expected `;' before '<' tokenbeides bezogen auf die Zeile:
Klasse<T>::Klasse():Kaempfer()
Wenn ich es direkt im Header mache, kommt wieder "undefinde reference to..".
-
struct A { }; struct Char { std::string name; int iTW; }; template <class T> class Klasse : public T, public Char { public: Klasse(); }; template <class T> Klasse<T>::Klasse() { name = "Sinthoras"; iTW = 1; };Schluckt mein Compiler :o
-
Z.Z. übersetzt er beide Versionen (also auch die falsche), wenn er lustig ist.
Wenn gerade lieber abstürzt, macht er auch das...


-
So mir war grad langweilig, hab dir hier nen Vorschlag. Schau mal ob er dir gefällt.
// Getestet, Pseudofunktionen als Bildschirmausgabe als Kontrolle obs geht #include <iostream> using namespace std; // Charakter Typen class Magier{ public: static void angreifen(){ cout << "zaubere();" << endl; } }; class Kaempfer{ public: static void angreifen(){ cout << "kaempfe();" << endl; } }; class Schurke{ public: static void angreifen(){ cout << "tu_schurkiges();" << endl; // naja Namen sind so ne Sache ;) } }; // Volktypen class Mensch{ public: static void rede( const std::string& text ){ cout << "sprich_menschisch( text );" << endl; } }; class Zwerg{ public: static void rede( const std::string& text ){ cout << "sprich_zwergisch( text );" << endl; } }; class Ork{ public: static void rede( const std::string& text ){ cout << "sprich_orkisch( text );" << endl; } }; // Spielfigur-Template template< typename CharakterT, typename VolkT > class Spieler{ public: void handle(){ VolkT::rede( "Halt, oder ich schiesse!" ); CharakterT::angreifen(); } }; int main() { // Jede Kombination möglich Spieler< Schurke, Zwerg > spieler1; Spieler< Kaempfer, Ork > spieler2; Spieler< Kaempfer, Mensch > spieler3; // Alle gleich zu bedienen aber verschiedenes Verhalten spieler1.handle(); spieler2.handle(); spieler3.handle(); }Du kannst nun jeden Spieler individuell erstellen, und auch jederzeit neue Charaktere oder Völker hinzufügen.
Nennt sich, wie schon gesagt, policy-based design und ist sehr flexibel.
-
Ja, danke, so hatte ich mir das vorgestellt

Sinthoras:
template<class Klasse, class Volk> class NSC : public Klasse, public Volk {... blabla alles hübsch kombinieren...};Entspricht ja auch ungeähr dem, was mich damit meinte.
Eine Frage aber noch:
Wenn ich das hier
template< typename CharakterT, typename VolkT > class Spieler{ public: void handle(){ VolkT::rede( "Halt, oder ich schiesse!" ); CharakterT::angreifen(); } };so (oder so änhlich) mache
template< typename CharakterT, typename VolkT > class Spieler : public CharakterT, public VolkT { public: (...) };Kann ich die Funktionen doch direkt aufrufen oder?
Also in main() z.B.
Spieler<Krieger, Zwerg> Gimli;
Gimli.angreifen();Oder nicht?
Danke jedenfall für Deine Mühe.
-
Hmm brauchst nicht unbedingt erben.
Kannst auch einfach weiterleiten:template< typename CharakterT, typename VolkT > class Spieler{ public: void angreifen(){ CharakterT::angreifen(); } }; //... Gimli.angreifen(); //...Der Vorteil davon ist, dass du keine vtable für die virtuellen Funktionen brauchst. Die Weiterleitung wird garantiert jeder einigermassen schlaue Kompiler wegoptimieren.
-
Aber ganz ohne Vererbug werde ich wohl nicht auskommen, denn ich möchte ja, dass der Magier Zauber bekommt, unser Freund Gimli hier aber nicht.
Wenn ich dann einfach in der Klasse Magier entsprechende Funktionen einbaue, in der Klasse Krieger aber nicht, hat sie am Ende eben auch nur der, der vom Magier erbt.
Also so hatte ich mir das jedenfalls gedacht...
-
Sinthoras schrieb:
Aber ganz ohne Vererbug werde ich wohl nicht auskommen, denn ich möchte ja, dass der Magier Zauber bekommt, unser Freund Gimli hier aber nicht.
Wenn ich dann einfach in der Klasse Magier entsprechende Funktionen einbaue, in der Klasse Krieger aber nicht, hat sie am Ende eben auch nur der, der vom Magier erbt.
Also so hatte ich mir das jedenfalls gedacht...
Ok da ist was dran.