Template + abstrakte Basisklasse



  • Hallo!
    Leider verstehe ich nicht ganz, warum der folgende Code nicht compiliert:

    class A
    {
    protected:
    	virtual bool operator=(const A& other) = 0;
    };
    
    template<typename T> class B : public A
    {
    protected:
    	bool operator=(const B<T>& other)
    	{
    		return false;
    	}
    };
    
    int main()
    {
    	B<int> a;
    	return 0;
    }
    

    Fehlermeldung ist:
    cannot declare variable `a' to be of type `B<int>'
    because the following virtual functions are abstract:
    virtual bool A::operator=(const A&)

    Ich verstehe durchaus, was das bedeuten soll 😉
    Aber wieso hat das mit dem Überladen vom Zuweisungsoperator nicht geklappt? 😕

    Ich wollte eigentlich auf diese Weise verhindern, dass jemand vergisst, den Zuweisungsoperator zu überschreiben, da die vom Comiler genegierte Version ja im Allgemeinen nicht ausreicht...
    Würde dass überhaupt Sinn machen?

    Vielen Dank schon mal für eure Erklärungen.

    Sne11ius



  • Sne11ius schrieb:

    Aber wieso hat das mit dem Überladen vom Zuweisungsoperator nicht geklappt? 😕

    Weil der Zuweisungsoperator der neuen Klasse eine andere Signatur hat als der der Basisklasse. Du überschreibst ihn also, statt ihn zu überladen. Virtuelle Zuweisungsoperatoren sind in den meisten Fällen keine gute Idee.
    Wenn du erzwingen willst, dass abgeleitete Klassen den op= implementieren, kannst du das auf folgende Weise erreichen:

    Deklariere den operator=, implementiere ihn aber nicht und/oder deklariere ihn als private.
    Da der compilergenerierte op= der abgeleiteten Klasse den op= der Basisklasse aufruft, würde das bei fehlender Implementierung zum Linkerfehler führen, bei privaten Basis-op= zum Compilerfehler. Du könntest eine assign()-Methode der Basisklasse protected anbieten, die den op= ersetzt und von den abgeleiteten Klassen im op= aufgerufen werden kann.



  • pumuckl schrieb:

    Deklariere den operator=, implementiere ihn aber nicht und/oder deklariere ihn als private. [...] Du könntest eine assign()-Methode der Basisklasse protected anbieten, die den op= ersetzt und von den abgeleiteten Klassen im op= aufgerufen werden kann.

    Habe ihn als private deklariert, da ich die Fehler lieber schon beim compilieren sehe...
    Die assign()-Methode werde ich nicht brauchen, da ich mit der Basisklasse nur verhindern will, das man mal vergisst den Operator zu überschreiben und dann lange nach Fehlern suchen muss. Folglich wird die Basisklasse auch nicht mehr enthalten ausser op= und op== (mit letzterem habe ich das Gleiche im Sinn)...

    Danke für die schnell Antwort: Sne11ius



  • Sne11ius schrieb:

    Habe ihn als private deklariert, da ich die Fehler lieber schon beim compilieren sehe...

    Ist auch besser so 😉

    op== (mit letzterem habe ich das Gleiche im Sinn)...

    op== wird nicht compilergeneriert, da ist das also nicht nötig. Der sollte außerdem als freie Funktion überladen werden (siehe Magazinartikel zur Operatorüberladung)


Anmelden zum Antworten