Fehlende Definition?



  • Hallo!
    Ich habe ein kleines Projekt erstellt um ein wenig mit Templates zu experimentieren - leider bekomme ich aber folgende Fehler:

    1>Main.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: __thiscall cToken<int>::cToken<int>(void)" (??0?$cToken@H@@QAE@XZ)" in Funktion ""public: __thiscall cTokenPlus<int>::cTokenPlus<int>(void)" (??0?$cTokenPlus@H@@QAE@XZ)".
    
    1>Main.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""public: virtual int __thiscall cTokenPlus<int>::calculate(int,int)" (?calculate@?$cTokenPlus@H@@UAEHHH@Z)".
    

    Ich habe eine Basisklasse Token:

    template <class T>
    class cToken{
    
    	public:
    
    	cToken();
    
    	~cToken();
    
    	T virtual calculate(T arg1, T arg2)=0;
    
    };
    

    .cpp:

    #include "Token.h"
    
    template <class T>
    cToken<T>::cToken(){
    
    }
    template <class T>
    cToken<T>::~cToken(){
    
    }
    

    Und mehrere davon abgeleitete Klassen - u.A. diese:

    template <class T>
    class cTokenPlus : public cToken<T>{
    
    	public:
    
    		cTokenPlus(){}
    
    		~cTokenPlus(){}
    
    	T calculate(T arg1, T arg2);
    
    };
    

    .cpp:

    #include "TokenPlus.h"
    
    template <class T>
    T cTokenPlus<T>::calculate(T arg1, T arg2){
    
    	return arg1 + arg2;
    }
    

    Und Main.cpp sieht so aus:

    #include <iostream>
    #include <map>
    #include <string>
    #include "stdafx.h"
    
    #include "TokenPlus.h"
    #include "TokenMinus.h"
    
    using namespace std;
    
    int main(){
    
    	map<string,cToken<int>*> Operators;
    
    	cTokenPlus<int> *c1=new cTokenPlus<int>();
    
    	Operators.insert(pair<string,cToken<int>*>("+",c1));
    
    	return 0;
    }
    

    Leider bekomme ich aber immer wieder diese LinkerFehler.
    Den Konstruktor und Destruktor von cTokenPlus habe ich im Header definiert, weil ich, als die Definition im cpp file war auch dafür die gleichen Linkerfehler bekommen habe.

    Ich möchte eine Map erzeugen in der ich Operatoren einfügen kann, denen ich später mit der calculate Methode verhaltensweisen zuordnen kann.
    Und eben ein Zeichen + einen Zeiger auf die dazugehörige Klasse darin speichern.
    Aber eben nur der Template-Vererbung-Übung wegen und nicht wegen des Programms selbst.
    Wäre toll, wenn ihr mir helfen könntet!
    MfG



  • Die Defintion deiner Templatefunktionen gehört ebenfalls in den Header.

    Siehe Frage 5:
    http://www.c-plusplus.net/forum/151578



  • Templates leben komplett im Header. Templates in .cpp Dateien funktionieren nicht, weil du das jedesmal mit kompilieren musst.



  • Vielen Dank für die schnellen Antworten!
    Funktioniert:)



  • drakon schrieb:

    Templates leben komplett im Header. Templates in .cpp Dateien funktionieren nicht, weil du das jedesmal mit kompilieren musst.

    Du meinst es sicher richtig, aber ich würde noch hinzufügen, dass man Templates sehr wohl in einer .cpp-Datei definieren kann, sofern man sie nur innerhalb dieser Datei benutzt. Also für lokale Hilfsfunktionen und -klassen.



  • Nexus schrieb:

    drakon schrieb:

    Templates leben komplett im Header. Templates in .cpp Dateien funktionieren nicht, weil du das jedesmal mit kompilieren musst.

    Du meinst es sicher richtig, aber ich würde noch hinzufügen, dass man Templates sehr wohl in einer .cpp-Datei definieren kann, sofern man sie nur innerhalb dieser Datei benutzt. Also für lokale Hilfsfunktionen und -klassen.

    Naja. Das ist ja grundsätzlich das gleiche. Die komplette Definition muss vor der Instanzierung bekannt sein. Ob das jetzt in einem Header passiert oder man es von Hand in einzelne .cpp's packt spielt ja keine Rolle mehr.(Edit: Ok, mein Satz ist vielleicht ein wenig missverständlich formuliert, aber es dient halt ein wenig dazu die Trennung intuitiv zu verstehen) Aber ich vermeide es sowieso zu viele Details einem Anfänger vor die Nase zu werfen. 😉

    Ein wirkliches Detail, wo man stutzen könnte, wäre, dass man Spezialisierungen in die .cpp packen kann. Aber üblicherweise hat man bis man mal auf das stösst ein gutes intuitives Verständnis erlangt, dass einem das dann einleuchtet.


Log in to reply