Virtual Dtor bei Interface Klassen?



  • Ich implementiere bisher in reinen Interface Klassen immer einen virtuellen Dtor rein. Weiß jemand, ob das zwingend nötig ist? Denn ich habe ja sowieso pure virtuelle Memberfunktionen, so das die Klasse "vererbar" ist.



  • Wenn du den Destruktor nicht virtuell machst, solltest du ihn (meistens) protected machen, um zu verhindern, dass delete auf einen Basisklassenzeiger aufgerufen wird (oder ähnliches passiert). Ein nicht virtueller Destruktor bedeutet natürlich, dass ein Objekt von dem man nur Basisklassenreferenzen besitzt nicht vernünftig zerstört werden kann. Ansonsten sollte es imho keine Probleme geben.

    Gruß
    Don06



  • OK, etwas unpräzise meine Frage. Deshalb nochmal genauer: ist überhaupt ein Dtor nötig? Weil den virtuellen Dtor habe ich drin, aber da es ja nur eine Interface Klasse ist, sind da absolut keine Membervariablen/resourcen drin, die aufgeräumt werden müssten.



  • Dann schau dir mal das an:

    #include <iostream>
    
    using namespace std;
    
    class A {
    public:
    	~A() {
    		cout << "I die" << endl;
    	}
    };
    
    class Base {
    public:
    	virtual void nothing() = 0;
    };
    
    class Derived : public Base {
    private:
    	A *res;
    
    public:
    	void nothing() {
    		res = new A;
    	}
    
    	~Derived() { // Wird nie aufgerufen, ist von der Basisklasse verdeckt
    		delete res;
    	}
    };
    
    int main() {
    	Base *b = new Derived;
    	b->nothing();
    	delete b;
    }
    

    Was denkst du, was passiert? Der compilergenerierte Destruktor überdeckt immer den abgeleiteten, sodass nie der richtige aufgerufen wird. Ob die Basisklasse nun abstrakt ist, ist egal. Der Destruktor muss angegeben werden, als virtuell. Der Compiler macht das nun mal nicht. Ist doch egal, ob er leer ist.



  • "überdeckt" ist hier entschieden das falsche wort.

    @Artchi:
    es geht nur darum, ob deine objekte über interface-zeiger löschbar sind.
    wenn "delete interface_ptr;" OK ist, dann muss das interface natürlich einen virtuellen dtor haben.



  • Danke für die Antworten! Dann war ich also bisher immer korrekt, den virtuelle Dtor zu implementieren. 🙂



  • Artchi schrieb:

    OK, etwas unpräzise meine Frage. Deshalb nochmal genauer: ist überhaupt ein Dtor nötig? Weil den virtuellen Dtor habe ich drin, aber da es ja nur eine Interface Klasse ist, sind da absolut keine Membervariablen/resourcen drin, die aufgeräumt werden müssten.

    Eigentlich hat hustbaer ja bereits das richtige gesagt. Einfach mal nochmal zum klar stellen. Was in der Interface Klasse drin ist (wenn dort etwas wäre) würde das so oder so korrekt aufgeräumt. Aber es geht ja darum, dass die Klassen, die vom Interface erben korrekt aufgeräumt werden. Sprich deren Destruktor aufgerufen wird. Sprich, wenn du jetzt dein Objekt über einen Zeiger auf das Interface zerstören willst und du keinen virtuellen Destruktor hast, wird gar nicht erst geschaut, ob das Objekt noch weiter gebunden ist und nur das Interface Objekt zerstört. Also brauchst du einen virtuellen Destruktor, um bekannt zu machen, dass noch ein weitere abgeleitetes Objekt zerstört werden möchte.


Log in to reply