Problem mit Templates - Linkerfehler



  • Hallo c-plus-plus.de-Mitglieder,

    ich habe ein Problem mit meinen C++-Klassentemplates.

    Ich versuche in Unmanaged C++ eine Art Liste wie es sie in dem .NET Framework gibt nachzubauen. Dabei tritt leider ein komischer Linkerfehler auf, den ich mir nicht erklären kann:

    Fehler 1 error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: void __thiscall List<class TestClass>::Add(class TestClass)" (?Add@?List@VTestClass@@@@QAEXVTestClass@@@Z)" in Funktion "\_main". main.obj GenericList Fehler 2 error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: \_\_thiscall List::List(void)" (??0?List@VTestClass@@@@QAE@XZ)" in Funktion "_main". main.obj GenericList

    Und darauf der folgefehler:

    Fehler 3 fatal error LNK1120: 2 nicht aufgelöste externe Verweise. D:\Projekte\C++\GenericList\Debug\GenericList.exe GenericList

    Hier mein Code dazu:
    List.cpp:

    // Generische Liste
    // Copyright (C) by ****** ****** 2009
    //
    
    #include <stdio.h>
    #include "List.h"
    
    template<class T>
    List<T>::List(void)
    {
    
    }
    
    template<class T>
    void List<T>::Add(T item)
    {
    
    }
    
    template<class T>
    T List<T>::operator[](int index)
    {
    
    }
    

    List.h:

    // Generische Liste
    // Copyright (C) by ****** ****** 2009
    //
    
    #pragma once
    
    template<class T> 
    class List
    {
    public:
    	// Constructor
    	List(void);
    
    	// Functions
    	void Add(T item);
    
    	// Operators
    	T operator[](int index);
    
    private:
    	T* items;
    	int itemCount;
    };
    

    Und main.cpp:

    // Listentest
    //
    
    #include <stdio.h>
    #include "TestClass.h"
    #include "List.h"
    
    int main(int argc, char** argv)
    {
    	List<TestClass> list;
    	TestClass test1;
    	test1.PrintMessage("Hallo");
    	list.Add(test1);
    
    	return 0;
    }
    

    'TestClass' ist eine simple Klasse die einen String ausgibt und den zuletzt ausgegeben speichert.

    Ich habe schon bei Google und in der MSDN gesucht, konnte aber keinen Fehler finden. 😕

    Achja, nochwas: Mein Compiler ist der aus Visual Studio 2008 Professional.

    Vielleicht sieht ja jemand den Fehler, meine C/C++ Kenntnisse sind noch anfängerig 😉

    mfg.
    markus111



  • templates kannst du mit dem MSVC nicht in .cpp's definieren.

    Dafür gäbe es das Schlüsselwort export, was von VC nicht unterstützt wird. 😉

    Also alles in den Header packen.

    btw.
    Wenn du schon C Header benutzt, dann richtig:

    #include <cstdio>
    

    Ist das richtige pendant in C++ zu stdio.h.



  • Alle Template-Definitionen müssen mit in die .h-Datei.



  • drakon schrieb:

    templates kannst du mit dem MSVC nicht in .cpp's definieren.

    Dafür gäbe es das Schlüsselwort export, was von VC nicht unterstützt wird. 😉

    Also alles in den Header packen.

    btw.
    Wenn du schon C Header benutzt, dann richtig:

    #include <cstdio>
    

    Ist das richtige pendant in C++ zu stdio.h.

    Ok, der Fehler ist weg 🙂 Aber wenn ich alles in der Headerdatei definiere, kann ich keine Funktionen wie memset und printf aufrufen!?! 🙄
    Ich habe den Header cstdio auch eingebunden.
    Oder mach ich da was falsch 😃 ?

    mfg.
    markus111

    PS: Sorry, hatte vergessen das ich mich schonmal registriert hatte :p



  • markus111 schrieb:

    Aber wenn ich alles in der Headerdatei definiere, kann ich keine Funktionen wie memset und printf aufrufen!?! 🙄
    Ich habe den Header cstdio auch eingebunden.
    Oder mach ich da was falsch 😃 ?

    Scheint so, kannst du diesbezüglich etwas konkreter werden? Wie sieht dein Code aus, welche Fehlermeldungen hast du wo erhalten?



  • Er hat wahrscheinlich auch aus stdlib.h cstdlib u.s.w. gemacht. Die Funktionen, liegen dann alle im std:: Namensraum



  • Hier mal mein Code:

    // Generische Liste
    // Copyright (C) by ****** ****** 2009
    //
    
    #pragma once
    
    #include <cstdio>
    
    template<class T> 
    class List
    {
    public:
    	// Constructor
    	List(void)
    	{
    
    	}
    
    	// Functions
    	void Add(T item)
    	{
    		int i = 0;
    		memset(&i, 0, sizeof(int));
    		printf(i);
    	}
    
    	// Operators
    	T operator[](int index)
    	{
    
    	}
    
    private:
    	T* items;
    	int itemCount;
    };
    

    fehler:

    Fehler 1 error C3861: "memset": Bezeichner wurde nicht gefunden. d:\projekte\c++\genericlist\genericlist\list.h 25 GenericList

    vllt ist meine verwendung der methoden etwas daneben, es geht nur darum das es funzt.

    mfg.
    markus111



  • hat sich ganz plötzlich erledigt, jetzt gehts....

    mfg.
    markus111



  • entweder, Du schreibst am Anfang ein mal "using namespace ::std;" (nicht empfohlen), oder Du schreibst "std::memset"...



  • Mr X schrieb:

    entweder, Du schreibst am Anfang ein mal "using namespace ::std;"

    auf keinen fall im header!



  • Und hier ein gutes Beispiel für die Begründung:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-247906.html


Anmelden zum Antworten