Template-Destruktor kann nicht gefunden werden
-
queue.h
template < class ta > class TQueue { protected: TQueueNode < ta > mHead; TQueueNode < ta > mTail; public: inline TQueue < ta > () { } inline TQueue < ta > (ta* in_data, bool in_deleteDataWhenDestroying=false) { // some little unimportant stuff } ~TQueue < ta > (); };Außerdem wird in dieser Datei noch die Template-Klasse
template < class ta > class TQueueNodedefiniert, die uns nicht interessiert.
In der Datei queue.cpp wird der in der Header-Datei nur deklarierte Destruktor implementiert (zumindest sollte dies so sein):
#include "queue.h" template < class ta > TQueue < ta >::~TQueue < ta > () { // some unimportant stuff (can be left empty for the problem) }Nun zu meiner Frage:
Im Testprogramm steht folgender Code:
#include "queue.h" int main(int argc, char** argv) { TQueue<int> test_queue=TQueue<int>(); }Das Problem:
Der Compiler sieht dies als Fehler und meint:new_dudos_client error LNK2019: Nicht aufgelöstes externes Symbol '"public: __thiscall TQueue<int>::~TQueue<int>(void)" (??1?$TQueue@H@@QAE@XZ)', verwiesen in Funktion '_main'
Der Destruktor konnte also nicht gefunden werden. Aber warum? Er steht doch in queue.cpp drin.
-
Verschieb die Implemetierung des Destruktors mal in den Header. Dazu solltest du bei der Suche im Forum einiges finden.
-
OK, ich habe es ausprobiert:
wenn ich den Destruktor als inline-Funktion in den Heade einbaue funktioniert es so, wie es soll (da jedoch im Destruktor ein "bißchen mehr" an Aufräumarbeit zu erledigen ist, möchte ich es jedoch nicht gerne als inline-Funktion im Header haben).
-
Template-Funktionen MÜSSEN im Header definiert werden, sonst kann der Compiler sie nicht instanziieren.
PS: in der Klassendeklaration brauchst du die TQueue<ta> übrigens nicht unbedingt.
-
OK, danke.
-
wolfgke schrieb:
OK, danke.
zumindest musst du ein #include "implementierungsdatei.endung" drin haben
-
Ich habe mal einen Blick auf älteren Code von mir geworfen. Da kommt zwar kein Template-Destruktor vor, jedoch wohl Template-Funktionen, die in externen Dateien implementiert sind.
So wie z. B. in einer Datei vector.h (Auszug)
template < unsigned int dim > class TVector { protected: float x[dim]; public: inline TVector() { } TVector < dim > operator+(TVector < dim >& in_v); };und in vector.cpp
#include "vector.h" template < unsigned int dim > TVector < dim > TVector<dim>::operator+(TVector < dim >& in_v) { // foo }(und der Code funktioniert, wenn ich mich nicht täusche (ist jedoch älterer Code, den ich nicht nicht mehr so genau kenne)).
Von daher bin ich doch ein wenig verwirrt.
Gilt diese Regel "Template muss in Header sein" möglicherweise nur für Konstruktor- und Destruktor-Funktionen?
-
Gilt diese Regel "Template muss in Header sein" möglicherweise nur für Konstruktor- und Destruktor-Funktionen?
Nope. Die Regel "Die Definition eines Templates muss überall dort sichtbar sein, wo das Template benutzt wird" gilt für alle Template-Funktionen. Und da die wenigsten Compiler das Schlüsselwort export unterstützen, heißt das in der Umsetzung "die Definitionen müssen in den Header".
Die Probleme deines Vektor-Codes siehst du spätestens dann, wenn du in zwei verschiedenen Übersetzungseinheiten zwei unterschiedliche Instanziierungen durchführst. In diesem Fall wirst du mit Sicherheit Linker-Fehler erhalten. Es sei denn natürlich du inkludierst (#include) die cpp-Datei. Was natürlich keine gute Idee ist.
-
Nein, normalerweise gilt das für alle Template-Funktionen. Aber du kannst ja mal nachschauen, welche Datei du bei deinem Uralt-Projekt #include't hast.
zumindest musst du ein #include "implementierungsdatei.endung" drin haben
Die kannst du auch noch als "Header" betrachten

PS: Der Linker-Fehler meldet sich übrigens erst, wenn du versuchst, die Template-Funktion zu verwenden, und das ist bei Konstruktoren und Destruktoren eher der Fall als z.B. bei einem Operator+.
-
Nein das gilt für alle Methoden
-
CStoll (off) schrieb:
PS: Der Linker-Fehler meldet sich übrigens erst, wenn du versuchst, die Template-Funktion zu verwenden, und das ist bei Konstruktoren und Destruktoren eher der Fall als z.B. bei einem Operator+.
Guter Hinweis

BR evilissimo
-
CStoll (off) schrieb:
PS: Der Linker-Fehler meldet sich übrigens erst, wenn du versuchst, die Template-Funktion zu verwenden, und das ist bei Konstruktoren und Destruktoren eher der Fall als z.B. bei einem Operator+.
OK, dann ist die Sache jetzt (hoffentlich) endgültig geklärt. Danke an alle Helfer.