Skip to content

Latest commit

 

History

History
89 lines (65 loc) · 1.92 KB

File metadata and controls

89 lines (65 loc) · 1.92 KB

Virtueller Destruktor

Zurück


Quellcode


Allgemeines

Virtuelle Destruktoren sind nützlich, wenn Sie möglicherweise eine Instanz einer abgeleiteten Klasse über einen Zeiger auf die Basisklasse löschen. Wir betrachten das folgende Beispiel:

class Base
{
public:
    ~Base()
    {
        // do some important cleanup in class Base
        std::cout << "d'tor Base" << std::endl;
    }

    // some virtual methods
    virtual void doSomething() {}
};

und eine davon abgeleitete Klasse Derived:

class Derived : public Base
{
public:
    ~Derived()
    {
        // do some important cleanup in class Derived
        std::cout << "d'tor Derived" << std::endl;
    }
};

Wir verwenden beide Klassen Base und Derived nun wie folgt:

Base* b = new Derived();
delete b; // here's the problem!

Welche Ausgaben in der Konsole erwarten Sie? Sie werden überrascht sein:

d'tor Base

Da der Destruktor von Base nicht virtuell ist und b ein Base*-Zeiger ist, der auf ein von Base abgeleitetes Objekt zeigt, hat die Anweisung delete b ein undefiniertes Verhalten.

In den meisten Implementierungen wird der Aufruf des Destruktors wie jeder nicht virtuelle Code aufgelöst, was bedeutet, dass der Destruktor der Basisklasse aufgerufen wird, jedoch nicht der der abgeleiteten Klasse, was zu Ressourcenleaks führen kann!

Zusammenfassend lässt sich sagen, dass Destruktoren einer Basisklasse immer virtuell deklariert sein sollten, wenn sie auf Grund eines polymorphen Szenarios aufgerufen werden sollten.

Wenn Sie in unserem Beispiel den Destruktor von Base in

virtual ~Base()
{
    // do some important cleanup in class Base
    std::cout << "d'tor Base" << std::endl;
}

abändern, also nur das Schlüsselwort virtual hinzufügen, lautet die Programmausgabe wie gewünscht

d'tor Derived
d'tor Base

Zurück