Visual C++: LNK2020: nicht aufgelöstes Token (0A00002F) Cvektor<int>.__dtor
-
Hi, ich bin neu hier und habe ein kleines problem, den ich bekomme einen Link-Fehler:
3 Dateien VektorProg.cpp
Vektor.cpp
Vektor.hVektor.h
#pragma once #include <iostream> template <class T> class Cvektor; template <class T> std::istream& operator>>(std::istream& eingabe, const Cvektor<T>& Vektor); template <class T> std::ostream& operator<<(std::ostream& ausgabe, const Cvektor<T>& Vektor); template <class T> class Cvektor { friend std::istream& operator>> <T>(std::istream& eingabe, const Cvektor<T>& Vektor); friend std::ostream& operator<< <T>(std::ostream& ausgabe, const Cvektor<T>& Vektor); private: unsigned int n; T* komp; public: Cvektor(unsigned int dimension); Cvektor(const Cvektor<T>& Vektor); ~Cvektor(); Cvektor<T> operator+(const Cvektor<T>& Vektor); Cvektor<T> operator-(const Cvektor<T>& Vektor); T operator*(const Cvektor<T>& Vektor); Cvektor<T>& operator=(const Cvektor<T>& Vektor); };Vektor.cpp
#include ".\Vektor.h" template<class T> Cvektor<T>::Cvektor(unsigned int dimension) { n=dimension; komp=new T[n]; } template<class T> Cvektor<T>::Cvektor(const Cvektor<T>& Vektor) { n=Vektor.n; delete[] komp; komp=new T[n]; for(int i=0;i<static_cast<int>(n);i++) komp[i]=Vektor.komp[i]; } template<class T> Cvektor<T>::~Cvektor() { delete[] komp; } template<class T> Cvektor<T> Cvektor<T>::operator+(const Cvektor<T>& Vektor) { Cvektor<T> Ergebnis(n); if(n==Vektor.n) { for(int i=0;i<static_cast<int>(n);i++) Ergebnis.komp[i]=komp[i]+Vektor.komp[i]; } else std::cout<<std::endl<<"Die beiden Vektoren sind fuer Addition nicht kompatibel!"; return Ergebnis; } template<class T> Cvektor<T> Cvektor<T>::operator-(const Cvektor<T>& Vektor) { Cvektor<T> Ergebnis(n); if(n==Vektor.n) { for(int i=0;i<static_cast<int>(n);i++) Ergebnis.komp[i]=komp[i]-Vektor.komp[i]; } else std::cout<<std::endl<<"Die beiden Vektoren sind fuer Subtraktion nicht kompatibel!"; return Ergebnis; } template<class T> T Cvektor<T>::operator*(const Cvektor<T>& Vektor) { T Ergebnis; if(n==Vektor.n) { for(int i=0;i<static_cast<int>(n);i++) { T t1=komp[i]; T t2=Vektor.komp[i]; Ergebnis=Ergebnis+t1*t2; } } else std::cout<<std::endl<<"Die beiden Vektoren sind fuer Multiplikation nicht kompatibel!"; return Ergebnis; } template<class T> Cvektor<T>& Cvektor<T>::operator=(const Cvektor<T>& Vektor) { delete[] komp; n=Vektor.n; komp=new T[n]; for(int i=0;i<static_cast<int>(n);i++) komp[i]=Vektor.komp[i]; return *this; } template<class T> std::istream& operator>>(std::istream& eingabe, const Cvektor<T>& Vektor) { std::cout<<"Geben sie die Komponenten des Vektors ein."<<std::endl; for(int i=0;i<static_cast<int>(Vektor.n);i++) { std::cout<<"Geben sie die Komponente "<<i<<" des Vektors ein: "; eingabe>>Vektor.komp[i]; } std::cout<<std::endl<<"EINGABE BEENDET"<<std::endl; return eingabe; } template<class T> std::ostream& operator<<(std::ostream& ausgabe, const Cvektor<T>& Vektor) { ausgabe<<std::setw(5)<<"("; for(int i=0;i<static_cast<int>(Vektor.n);i++) { if(i==(Vektor.n-1)) ausgabe<<std::setw(7)<<Vektor.komp[i]<<")^T"; else ausgabe<<std::setw(7)<<Vektor.komp[i]<<","; } return ausgabe; }VektorProg.cpp
#include <iostream> #include "Vektor.h" int main() { Cvektor<int> A(3); //Dieser Code reicht aus um den Link Error zu erzeugen system("pause"); }LINKER gibt aus: LNK2020: nicht aufgelöstes Token (0A00002F) Cvektor<int>.__dtor
Ich benutze Visual Studio 2003 mit Studentenlizenz und habe .NET Framework 2.0 installiert
Für hilfe zu dieser Fehlermeldung, die ausführlicher ist als die von MSDN wäre ich sehr dankbar
Martin
-
Deklaration und Definition eines templates müssen in der Übersetzungseinheit bekannt sein, in der sie verwendet werden.
Das heißt du hast verschiedene Möglichkeiten:
[list][]Packe beides in eine Datei (inline in die klasse oder darunter)
[]Nenn die Vektor.cpp in Vektor.impl um und inkludiere diese am Ende der anderen Datei
[*]Schlüsselwort export, implementiert nur leider fast kein Compileredit: siehe C++ FAQ und da Nr. 5
MfG
DDR-RAM
-
Hi, ich habe das Problem mit deiner Hilfe gelöst.
Da mein Template nicht so globig war hab ich alles in den header gesteckt. Ob das nun den Gepflogenheiten entspricht oder auch nicht.
Trotzdem gefällt mir die Lösung mit den *.impl-Dateien besser.DDR-RAM schrieb:
[*]Nenn die Vektor.cpp in Vektor.impl um und inkludiere diese am Ende der anderen Datei
Da hatte ich aber das Problem, dass der Compiler plötzlich meinte, dass alle friend und member functions schon definiert seien, dabei wurden sie in dem Template lediglich deklariert. Oder ist mit inkludieren noch mehr als der preprocessor command
#includegemeint? Hmm Naja. Wenn du da noch nen Tipp hättest, wär super.
Martin
-
Also ich hab rausgefunden, warum der Compiler Probleme mit der inkludierten Datei hatte. Ich hatte sie nähmlich nicht in .impl umbenannt, sondern als .cpp gelassen. Wenn man nun .impl oder andere für Visual C++ unbekannte source file Endungen verwendet nutzt VC++ automatisch ein Benutzerdefiniertes Buildtool (frag mich nicht was das ist). Benutzt man eine bekannte Endung, so wird das C++ Compiler Tool automatisch ausgewählt. Das C/C++ Compiler Tool führt zu diesen Fehlern. Mit dem Benutzerdefinierten Build Tool gibt der Compiler keine Fehler aus. Ich weis natürlich nicht, ob das eine Tücke der Entwicklungsumgebung ist oder nicht, aber vielleicht hilft es ja mal jemandem weiter.
Das Programm lässt sich jedoch in beiden Fällen debuggen. Das ist ein bischen komisch!
Gruß Martin
-
Die cpp-Dateien werden standardmäßig in einer eigenen Übersetzungseinheit kompiliert. Das heißt, der Compiler kompiliert auch die Datei vektor.cpp.
In dieser Datei stand bei dir wahrscheinlich noch #include "vektor.h".
In dieser wird dann wieder vektor.cpp inkludiert und du hast alle member und friends doppelt definiert. Das darf natürlich nicht sein und er meckert.
Wenn vektor.cpp nicht selbst kompiliert wird, sondern nur VektorProg.cpp, dann wird vektor.h eingebunden und diese bindet dann vektor.cpp bzw. vektor.impl ein. Wenn du dort noch #include "vektor.h" stehen hast passiert dir nichts, weil vektor.h ja durch #pragma once geschützt ist.
Also umbennenen und in vektor.impl#include "vektor.h"entfernen, da diese datei ja nur vom ende von vektor.h aus inkludiert werden sollte, womit vektor.h schon eingebunden ist.
MfG
DDR-RAM