Template Anfänger-Frage



  • Hi leute,

    ich hab ein kleines Problem mit Templates.
    Ich wollte zu Beginn ein kleines Template Beispiel codieren.

    Hier mein Code:

    main.cpp

    #include <iostream>
    #include "container.h"
    
    int main(int argc, char *argv[]) {
    	int *myInt = new int(2);
    	Container<int> myContainer(myInt);
    	std::cout << "myStr von myContainer: " << myContainer.getValue() << std::endl;
    	delete myInt;
    	return 0;
    }
    

    container.h

    #ifndef CONTAINER_H_
    #define CONTAINER_H_
    
    template <typename T> class Container {
    private:
    	T *value;
    public:
    	Container();
    	Container(T *value);
    	~Container();
    	T getValue();
    	void setValue(T *value);
    };
    
    #endif
    

    container.cpp

    #include "container.h"
    
    template<typename T>
    Container<T>::Container() {
    	*value = new T();
    }
    
    template<typename T>
    Container<T>::Container(T *a_value) {
    	*this->value = *a_value;
    }
    
    template<typename T>
    void Container<T>::setValue(T *a_value) {
    	*this->value = *a_value;
    }
    
    template<typename T>
    T Container<T>::getValue() {
    	return *this->value;
    }
    
    template<typename T>
    Container<T>::~Container() {
    	delete value;
    }
    

    irgendwie bring ich das ding nicht zum laufen. Visual C++ bringt diesen Fehler:

    Testumgebung error LNK2019: Nicht aufgelöstes externes Symbol '"public: __thiscall Container<int>::~Container<int>(void)" (??1?$Container@H@@QAE@XZ)', verwiesen in Funktion '_main'
    
    Testumgebung error LNK2019: Nicht aufgelöstes externes Symbol '"public: int __thiscall Container<int>::getValue(void)" (?getValue@?$Container@H@@QAEHXZ)', verwiesen in Funktion '_main'
    

    etc.

    Ich hoffe einer kann mir hier weiterhelfen und mir vielleicht einen Tipp geben wie ich das Teil zum laufen bringe.

    Danke. mfg byte



  • Definition und Deklaration in den Header packen.



  • Hm...
    im prinzip richtig,

    benenne aber mal lieber die .cpp in z.B. .impl um und includiere das im Container.h - hilft wenn mal die Zeit kommt in der export auch untersützt wird 🙂

    (Der Compiler erstellt im Prinzip den Quellcode an der Stelle an der er benötigt wird. Aus Deinem Template wird eine konrekte Klasse mit passenden Typ(en) erzeugt. Wenn der Container.cpp compilieren würde, wüsste er garnicht für welche Typen dies alles geschehen soll).


  • Mod

    oder in der container.cpp explizit instantiieren.



  • Was sich in der Praxis wohl nich machen lässt und dem Template entgegen wirkt, denn weil wir genau das nicht machen wollen, nutzen wir doch das Template



  • hmm also irgendwie klappt das immer nocht nichtl.
    Vielleicht noch einen Tipp irgendjemand?

    @Knuddlbaer
    ehhmmm hä ? 😕

    mgf byte



  • Dasda

    ByteRix schrieb:

    template<typename T>
    Container<T>::Container() {
    	*value = new T();
    }
    
    template<typename T>
    Container<T>::Container(T *a_value) {
    	*this->value = *a_value;
    }
    
    template<typename T>
    void Container<T>::setValue(T *a_value) {
    	*this->value = *a_value;
    }
    
    template<typename T>
    T Container<T>::getValue() {
    	return *this->value;
    }
    
    template<typename T>
    Container<T>::~Container() {
    	delete value;
    }
    

    in den Header!



  • ah ok danke funktioniert 🙂

    aber ist es dann gar nicht möglich die Definition(Implementierung) in eine extra cpp auszulagern bei templates?

    mfg byte



  • derzeit unterstützen das die Compiler nicht (es mag bereits ausnahmen geben).

    Daher bietet es sich immer an die .cpp umzubenennen und per include an den header zu packen. Dann kann man das später leichter auftrennen 🤡



  • fragen stehen als kommentar

    ByteRix schrieb:

    template<typename T>
    Container<T>::Container() {
    	*value = new T();             //wieso hier *value und nicht nur value?
    }
    
    template<typename T>
    Container<T>::Container(T *a_value) {
    	*this->value = *a_value;      //same bei this und a_value;
    }
    
    template<typename T>
    void Container<T>::setValue(T *a_value) {
    	*this->value = *a_value;     //same
    }
    
    template<typename T>
    T Container<T>::getValue() {
    	return *this->value;        //same
    }
    
    template<typename T>
    Container<T>::~Container() {
    	delete value;
    }
    

    denn ich habe das ja immer so gemacht:

    [cpp]
    muss das da so sein?
    wenn ja warum?



  • Knuddlbaer schrieb:

    derzeit unterstützen das die Compiler nicht (es mag bereits ausnahmen geben)....

    Wobei man fairerweise sagen muß, dass dazu das Schlüsselwort "export" zu verwenden wäre und es Compiler/Linker bei templates nicht so "automatisch" machen sollen (vom Standard her gesehen) wie bei Funktionen und Klassen.

    Gruß,

    Simon2.



  • Value ist bei Dir ein Zeiger. Um dessen Wert zu ändern muss dieser dereferenziert werden, dazu das * davor.

    T *value;
    
    value=0x4711; // Adresse von Value ändern
    *Value=0x4711; // Den Wert von Value ändern
    

Anmelden zum Antworten