Template-Klassen-Problem



  • Hallo,

    ich versuche gerade einmal eine Template-Klasse zu entwerfen und habe es dann auch endlich geschafft, nur gibt
    es bei der weiteren Implementierung ein Problem mit dem Linker und ich weiß nicht woran das liegt. Ich hoffe
    ihr könnt mir da weiter helfen!

    Zuerst einmal kommt hier der das Problem betreffene Teil der Template-Klasse. Diese Klasse ist übrigens fertig implementiert und alles wird korrekt kompiliert, etc. Die Klasse CVector wird dabei vorausgesetzt, die ist hier nicht von Interesse!

    template <class TYPE> class CCellularAutomata
    {
    public:
    	TYPE	getCellState( CVector vecCellPos );
    	virtual TYPE translateCell( CVector vecCellPos ) = 0;
    }
    
    template<class TYPE> TYPE CCellularAutomata<TYPE>::getCellState( CVector vecCellPos )
    {
    	uint32	intOffset = 0;
    	uint32	intFactor = 1;
    
    	for (uint32 intCounter=0; intCounter<vecCellPos.getDimension(); intCounter++)
    	{
    		intOffset += (vecCellPos.getItem(intCounter) % intSize) * intSize;
    		intFactor *= intSize;
    	}
    
    	if (intOffset < intCellCount)	return fooCell[intOffset];
    	return NULL;
    }
    

    Jetzt habe ich hier noch die Implemtierung der abstrakten Funktion translateCell in einer Subklasse!

    class CShrinkAutomata : public CCellularAutomata<strucCell>
    {
    public:	
    	strucCell translateCell(  CVector vecCellPos );
    };
    

    Hierbei ist strucCell eine einfache Struktur, die z.B. folgendermaßen definiert sein könnte:

    struct strucCell
    {
    	int	intColor;
    	double	dblIrgendwas;
    };
    

    Soweit so gut, versuche ich jetzt aber die Funktion aus CShrinkAutomata zu implementieren, so gibt es ein Problem!

    strucCell	CShrinkAutomata::translateCell( CVector vecCellPos )
    {
    	/* strucCell	oldCell = getCellState( vecCellPos ); */
    	strucCell	newCell;
    	return 		newCell;
    }
    

    Bis jetzt kompiliert und linkt der Compiler alles, aber wenn ich hier die auskommentierte Zeile hereinnehme, dann bricht der Compiler mit folgender Fehlermeldung ab:
    shrink.obj : error LNK2001: Nichtaufgeloestes externes Symbol "public: struct strucCell __thiscall CCellularAutomata<struct strucCell>::getCellState(class CVector)" (?getCellState@?$CCellularAutomata@UstrucCell@@@@QAE?AUstrucCell@@VCVector@@@Z)
    Debug/QueenBee.exe : fatal error LNK1120: 1 unaufgeloeste externe Verweise

    Habe ich irgendwas falsch gemacht oder etwas übersehen?

    Pomplito



  • Hi,

    if (intOffset < intCellCount)    return fooCell[intOffset];
    

    was ist fooCell[]? Sollte es hier nicht etwas vom Typ <TYPE> zurück gegeben werden?



  • Hi, das ist aber von selben Typ, das hatte ich nur vergessen anzugeben, also so:

    template <class TYPE> class CCellularAutomata
    {
    public:
    	TYPE	getCellState( CVector vecCellPos );
    	virtual TYPE translateCell( CVector vecCellPos ) = 0;
    
    private:
    	TYPE	*fooCell;
    };
    

    Dieses Feld wird dann dynamisch erstellt, etc. (intCellCount ist übrigens ein Integer)



  • Nur zur Sicherheit: Hast du die Definition von CCellularAutomata::getCellState() auch mit im Header stehen?



  • Ja natürlich, ich habe immer mein .h File mit den Definitionen und das .cpp File mit der Implementation... 😕



  • Du meinst Du hast die Deklaration im Header und die Definition (=Implementierung) in der .cpp-Datei? 😉

    Genau dort liegt der Fehler: Dem Compiler muss zur Instanzierung eines Templates die komplette Templatedefinition vorliegen, weshalb man die nicht in eine andere .cpp-Datei auslagern darf.



  • Nunja, man darf es schon. Problem ist nur, dass dafür export unterstützt werden müsste. Und das macht momentan so gut wie kein Compiler.


Anmelden zum Antworten