Templates Erben funktioniert nicht



  • Hallo,

    wir wollten eine virtuelle Klass schreiben von der dann später mehrere Klassen erben sollen und die Methoden überschreiben. Leider funktioniert dies gar nicht, da die erbende Klasse angeblich abstrakt ist, obwohl wir der Meinung sind alle rein virtuellen Funktionen überschrieben zu haben.

    Erstmal zum Code:

    main.cpp

    #include <windows.h>
    #include <iostream>
    #include "header/calculator.h"
    #include "stdio.h"
    #include "header/Integer.h"
    
    using namespace std;
    
    auto main()
    {
           AllocConsole();
    	freopen("conin$", "r", stdin);
    	freopen("conout$", "w", stdout);
    	freopen("conout$", "w", stderr);
    	printf("Debugging Window:\n");
    
    	Calculator<Integer> calc;
    	Integer i(2);
    	Integer g(3);
    	calc.sum(i, g);
    	cout << result.getInt();
    }
    

    arithmetic.h

    #pragma once
    using namespace std;
    
    template<class V>
    class Arithmetic {
    
    public:
    	/*
    	@returns V: sum of the values
    	*/
    	virtual V& sum(V& arg0) = 0;
    };
    

    integer.h

    #pragma once
    #include "arithmetic.h"
    
    using namespace std;
    
    class Integer : public Arithmetic<Integer>
    {
    
    private:
    
    public:
    	int value;
    	Integer(int value);
    	int Integer::getInt();
    };
    

    integer.cpp

    #include "header/Integer.h"
    
    Integer::Integer(int value)
    {
    	this->value = value;
    }
    
    int Integer::getInt()
    {
    	return this->value;
    }
    
    //hier sind wir ganz unsicher, ob die Vererbung so correkt ist. Haben schon viel hier 
    //ausprobiert. So findet VS wenigstens die richtige deklaration. Und es gibt keinen Fehler
    //bei "return result"
    template<class V>
    V& Arithmetic<V>::sum(V& arg0)
    {
    	int i = this->value + arg0.getInt();
    	Integer result(i);
    	return result;
    }
    

    calculator.h

    using namespace std;
    
    template<class V>
    class Calculator {
    public:
    
    	/*
    	@returns V: sum of the values
    	*/
    	V sum(V a, V b);
    
    };
    

    calculator.cpp

    #include "header\calculator.h"
    
    template<class V>
    V Calculator<V>::sum(V a, V b)
    {
    	V result = a.Arithmetic<V>::sum(b);
    	return result;
    }
    

    Fehlermeldungen:
    Schweregrad Fehler
    Code C2259
    Beschreibung "Integer": Instanz von abstrakter Klasse kann nicht erstellt werden

    Wir sind leider inzwischen komplett überfragt und bräuchten dringend Hilfe. Dafür schon mal danke.

    Mfg
    Ken



  • Der Compiler weiss ja gar nicht, was

    virtual V& sum(V& arg0) = 0
    

    machen soll, da du diese ja weder in der Basisklasse "Arithmetic noch in der abgeleiteten Klasse "Integer" implementiert hast.



  • Dies sollte unsere Implementierung in der abgeleiten Klasse sein.
    Ich weis nur wie man es in Java aufschreibt, wo natürlich dann alle V durch Integer ersetzt werden müssten. Jedoch in c++ haut es momentan nicht hin.
    Wie würde den die implementierung aussehen?

    template<class V>
    V& Arithmetic<V>::sum(V& arg0)
    {
        int i = this->value + arg0.getInt();
        Integer result(i);
        return result;
    }
    

    MFG
    Ken



  • Hallo,

    bisher hast du eine freie (Template-)Funktion definiert.
    Für die Ableitung müßtest du diese in der Klasse Integer deklarieren:

    class Integer : public Arithmetic<Integer>
    {
      public:
        // ...
    
      Integer& sum(Integer& arg0);
    };
    

    Und dann noch entsprechend in der Source-Datei definieren:

    Integer& Integer::sum(Integer& arg0)
    {
      // ...
    }
    

    So wäre es syntaktisch richtig, auch wenn es m.E. bessere Design-Möglichkeiten gibt (aber ich nehme mal an, daß dies eine Übungsaufgabe ist?).



  • So ich habe die Implementierung dann so weit übernommen und auch noch beim
    Rückgabewet die Referenzierung entfernt.
    Jedoch steht mir jetzt noch ein Linkerfehler im weg.

    Ja dieses Programm ist eine Übung. 🙂

    integer.h

    #pragma once
    #include "arithmetic.h"
    
    using namespace std;
    
    class Integer : public Arithmetic<Integer>
    {
    
    private:
    
    public:
         int value;
         Integer(int value);
         int getInt();
         Integer sum(Integer& arg0);
    };
    

    integer.cpp

    #include "header/Integer.h"
    
    Integer::Integer(int value)
    {
    	this->value = value;
    }
    
    int Integer::getInt()
    {
        return this->value;
    }
    
    Integer Integer::sum(Integer& arg0)
    {
    	int i = this->value + arg0.getInt();
    	Integer result(i);
    	return result;
    }
    

    Fehler:
    LNK2019 Verweis auf nicht aufgelöstes externes Symbol ""public: class Integer __cdecl Calculator<class Integer>::sum(class Integer,class Integer)" (?sum@?$Calculator@VInteger@@@@QEAA?AVInteger@@V2@0@Z)" in Funktion "main". PoketCalculator C:\Users\Ken Moller\Documents\Visual Studio 2015\Projects\PoketCalculator\PoketCalculator\main.obj 1



  • Du musst die Definition von Calculator::sum in den Header packen. Schließlich wird bei jedem aufruf dieser methode eine neuer methodenrumpf mit den entsprechenden template-typen generiert.



  • Leider hat das verlagern der Definition nichts gebracht.

    Der neue Header sieht wie folgt aus und die cpp ist gelöscht.

    #pragma once
    #ifndef CALCULATOR_H
    #define	CALCULATOR_H
    
    using namespace std;
    
    template<class V>
    class Calculator {
    public:
    
    	/*
    	@returns V: sum of the values
    	*/
    	V sum(V a, V b)
    	{
    		V result = a.Arithmetic<V>::sum(b);
    		return result;
    	}
    
    };
    

    Fehler LNK2019 Verweis auf nicht aufgelöstes externes Symbol ""public: virtual class Integer __cdecl Arithmetic<class Integer>::sum(class Integer &)" (?sum@?Arithmetic@VInteger@@@@UEAA?AVInteger@@AEAV2@@Z)"inFunktion""public:classInteger__cdeclCalculator<classInteger>::sum(classInteger,classInteger)"(?sum@?Arithmetic@VInteger@@@@UEAA?AVInteger@@AEAV2@@Z)" in Funktion ""public: class Integer \_\_cdecl Calculator<class Integer>::sum(class Integer,class Integer)" (?sum@?Calculator@VInteger@@@@QEAA?AVInteger@@V2@0@Z)". PoketCalculator C:\Users\Ken Moller\Documents\Visual Studio 2015\Projects\PoketCalculator\PoketCalculator\main.obj 1

    Freue mich auf weitere Hilfe.

    mfg
    Ken



  • Dieser Thread wurde von Moderator/in Martin Richter aus dem Forum MFC (Visual C++) in das Forum C++ (alle ISO-Standards) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Hi,
    der Header von calculator weiß gar nicht, was die Klasse Integer ist, du musst den Header von Integer noch mit #include einfügen.
    Und warum gehst du bei sum() den Umweg über die Basisklasse, du hast doch schon ein Objekt der Klasse integer, da kannst du die Funktion auch direkt ansprechen.

    Wie ist denn die Aufgabenstellung, das Programm scheint mir noch etwas konfus zu sein.

    Viele Grüße
    Cherup


Anmelden zum Antworten