"Weggelassener" Destruktor nicht automatisch virtual?



  • Kann es sein, dass, wenn ich einen Destruktor nicht explizit deklariere, dass er dann nicht automatisch virtual ist? Weil, wenn ich das hier schreibe:

    #include <iostream>
    
    using namespace std;
    
    class Basis
    {
    public:
    	Basis() { cout << "Basis Konstruktor\n"; }
    	// virtual ~Basis() { cout << "Basis Destruktor\n"; }
    };
    
    class Abgeleitet : public Basis
    {
    public:
    	Abgeleitet() { cout << "Abgeleitet Konstruktor\n"; }
    	virtual ~Abgeleitet() { cout << "Abgeleitet Destruktor\n"; }
    };
    
    int main()
    {
    	Basis *x = new Abgeleitet();
    
    	delete x;
    }
    

    wird der Destruktor von Abgeleitet nicht aufgerufen.

    Ich dachte bisher immer, dass Destruktoren per default virtual sind, aber dem scheint nicht so zu sein.
    Liege ich also richtig mit der Annahme, dass man, wenn man Vererbung nicht gerade verhindern will, einen Destruktor immer explizit deklarieren sollte, auch wenn er gar nichts macht?



  • joa is so



  • Grampa schrieb:

    Kann es sein, dass, wenn ich einen Destruktor nicht explizit deklariere, dass er dann nicht automatisch virtual ist?

    So ist es !

    Grampa schrieb:

    Liege ich also richtig mit der Annahme, dass man, wenn man Vererbung nicht gerade verhindern will, einen Destruktor immer explizit deklarieren sollte, auch wenn er gar nichts macht?

    Faustregel: Wenn die Klasse irgendwelche virtual Funktionen hat, sollte man ihr auch einen virtual Destruktor spendieren.



  • Du hast in allen Punkten recht.
    Außer vielleicht im letzten, ich denke nicht, daß man profilaktisch gleich *jeder* Klasse einen virtuellen Destruktor spendieren sollte, nur weil jemand auf die Idee kommen *könnte*, davon zu erben.



  • Grampa schrieb:

    Ich dachte bisher immer, dass Destruktoren per default virtual sind, aber dem scheint nicht so zu sein.

    Nein, sind sie nicht. Normalerweise müssen für virtuelle Funktionen (also auch virtuelle Destruktoren) extra Informationen pro Objekt gespeichert werden. Da in C++ aber die Politik "zahle für nichts was du nicht brauchst" gilt, wird keine virtuellen Funktionen geben, wenn du sie nicht deklarierst.

    Liege ich also richtig mit der Annahme, dass man, wenn man Vererbung nicht gerade verhindern will, einen Destruktor immer explizit deklarieren sollte, auch wenn er gar nichts macht?

    Bei Vererbung sollte der Destruktor von Basisklassen immer deklariert werden, und zwar entweder virtuell und public, wenn du Polymorphie nutzen willst, d.h vieruelle Funktionen hast, oder aber protected und nicht virtuell, wenn du nicht-polymorphe Basisklassen haben möchtest.



  • Wenn Destruktoren immer virtuell wären, wäre jede Klasse polymorph. Jede struct natürlich auch.
    Dann gäbe es keine PODs mehr.
    Der Standard müsste an 1000 Stellen umgeschrieben werden.
    Viele Optimierungen wären nichtmehr möglich.

    Kurz: die Welt würde in ihren Grundfesten erschüttert. Das wäre garnicht gut. Das wollen wir nicht.



  • Grampa schrieb:

    Liege ich also richtig mit der Annahme, dass man, wenn man Vererbung nicht gerade verhindern will, einen Destruktor immer explizit deklarieren sollte, auch wenn er gar nichts macht?

    Nein.

    Vererbung impliziert Polymorphie nicht. Oft werden die Techniken zusammen verwendet, aber längst nicht immer. Dynamische Polymorphie brauchst du nur, wenn du abgeleitete Objekte über Basisklassenverweise ansprechen willst.



  • Also eigentlich braucht man einen virtuellen Destruktor nur, wenn man eine Klasse über einen Basisklassenzeiger mittels delete löschen will. Dann sollte die Basisklasse einen virtuellen Destruktor haben. Und selbst dann gibt es Situationen, wo man das nicht unbedingt braucht.

    Aber das gehört sicher schon zur fortgeschrittenen C++-Programmierung. Die Regel, dass der Destruktor immer virtuell deklariert werden sollte, wenn die Klasse abgeleitet werden soll, ist gar nicht so falsch.



  • tntnet schrieb:

    Aber das gehört sicher schon zur fortgeschrittenen C++-Programmierung. Die Regel, dass der Destruktor immer virtuell deklariert werden sollte, wenn die Klasse abgeleitet werden soll, ist gar nicht so falsch.

    Ich würde nicht sagen generell abgeleitet, sondern abgeleitet mit dem Gedanken das ganze polymorph zu benutzen. Dann auf jeden Fall ja, wenn nicht dann sollte der auch nicht virtuell sein.


Anmelden zum Antworten