[solved] Nicht-Template-Klasse von Template-Klasse ableiten



  • Hallo,

    ich möchte gerne eine Klasse von einer Template-Klasse ableiten, wie im unteren Bsp. class PersonalID : public DataObject<int> . Das an sich scheint zu gehen, allerdings scheinen mir innerhalb der abgeleitenten Klasse die Methoden der Basis-Klasse nicht zur Verfügung zu stehen. Die Basis-Klasse scheint auch gar nicht konstruiert zu werden. Bei google konnte ich nur Lösungen finden, wo die abgeleitete Klasse auch eine Template-Klasse ist. Hat jemand eine Idee, wie ich den gleichen Effekt erreichen kann?

    #include <iostream>
    using namespace std;
    
    // general data object, used as basis for everything
    template<class T>
    class DataObject
    {
    	protected:
    		T data;
    
    	public:
    		DataObject() {}
    		DataObject(T& new_data)
    		{
    			data = new_data;
    			cout << "DataObject " << data << endl;
    		}
    		virtual T getData() const {return data;}
    };
    
    // all data objects of a certain type have special functions
    template<>
    class DataObject<int>
    {
    	protected:
    		int data; /** scheint unnoetig, aber nagut **/
    
    	public:
    		void specialIntFunction() {cout<< (data % 2) << endl;}
    };
    
    class PersonalID : public DataObject<int> /** nimmt der Compiler an **/
    {
    	public:
    		PersonalID(int id, bool neg_switch)
    		{
    			if(neg_switch) data = id;
    			else data = -id;
    			cout << "PersonalID " << data << endl;
    		}
    };
    
    class Counter : public DataObject<int>
    {
    	public:
    		Counter(int initial_count, int id) : DataObject<int>(initial_count) /** Fehler: keine passende Funktion für Aufruf von »DataObject<int>::DataObject(int&)« **/
    		{
    			cout << "Counter #" << id << " = " << initial_count << endl;
    		}
    };
    
    int main()
    {
    	Counter c(1, 42);
    	PersonalID pid(23, true);
    	PersonalID* ptr = & pid;
    	cout << "main " << ( ptr -> getData() ) << endl; /** Fehler: »class PersonalID« hat kein Element namens »getData« **/
    	return 0;
    }
    

    "danke im vor*aus" 😉



  • Da du die Template-Klasse DataObject spezialisiert hast (DataObject<int>) und du dort die Methode "getData()" nicht definiert hast, gibt es sie auch nicht ind er davon abgeleiteten Klasse PersonalID.
    Spezialisierung einer Klasse bedeutet also komplette Angabe aller Methoden (außer du vererbst wiederum von einer Basisklasse).



  • Weil die Spezialisierung keinen Konstruktor hat der einen int annimmt.

    /** Fehler: keine passende Funktion für Aufruf von »DataObject<int>::DataObject(int&)« **/
    

    Weil die Spezialisierung keine Funktion getData hat.

    /** Fehler: »class PersonalID« hat kein Element namens »getData« **/
    

    Wenn du diese implementieren würdest, dann sind auch die Fehler verschwunden.



  • Danke! 🙂

    (Tatsächlich compiled und läuft der Code ohne Spezialisierung wie erwartet. Da ich aber die spezialisierten Funktionen brauche, schreib ich halt die Zeilen quasi nochmal.)

    EDIT:
    (Falls jemand auf ein ähnliches Problem stößt.)
    Ich habe noch eine alternative Lösung gefunden - nämlich eine neue Klasse class DataObjectInt : public DataObject<int> zu definieren, und die anderen Klasse davon abzuleiten. Das erspart mir die Code-Dublizierung.

    #include <iostream>
    using namespace std;
    
    // general data object, used as basis for everything
    template<class T>
    class DataObject
    {
    	protected:
    		T data;
    
    	public:
    		DataObject() { cout << "empty DataObject" << endl; }
    		DataObject(T& new_data)
    		{
    			data = new_data;
    			cout << "DataObject " << data << endl;
    		}
    		virtual T getData() const {return data;}
    };
    
    class DataObjectInt : public DataObject<int>
    {
    	public:
    		DataObjectInt() : DataObject<int>() {}
    		DataObjectInt(int new_data) : DataObject<int>(new_data) {}
    
    		void specialIntFunction() {cout<< (data % 2) << endl;}
    };
    
    class PersonalID : public DataObjectInt
    {
    	public:
    		PersonalID(int id, bool neg_switch)
    		{
    			if(neg_switch) data = id;
    			else data = -id;
    			cout << "PersonalID " << data << endl;
    		}
    };
    
    class Counter : public DataObjectInt
    {
    	public:
    		Counter(int initial_count, int id) : DataObjectInt(initial_count)
    		{
    			cout << "Counter #" << id << " = " << initial_count << endl;
    		}
    
    };
    
    int main()
    {
    	Counter c(1, 42);
    	c.specialIntFunction();
    
    	PersonalID pid(23, true);
    	PersonalID* ptr = & pid;
    	cout << "main " << ( ptr -> getData() ) << endl;
    	return 0;
    }
    

Anmelden zum Antworten