Aufruf des Destruktors über einen Zeiger auf eine Basisklasse
struct Base {
virtual void f() {}
virtual ~Base() {}
};
struct Derived : Base {
void f() override {}
~Derived() override {}
};
Base* base = new Derived;
base->f(); // calls Derived::f
base->~Base(); // calls Derived::~Derived
Der Aufruf eines virtuellen Destruktors unterscheidet sich nicht von jedem anderen Aufruf einer virtuellen Funktion.
Für base->f()
wird der Anruf weitergeleitet an Derived::f()
und das Gleiche gilt für base->~Base()
- seine übergeordnete Funktion - die Derived::~Derived()
aufgerufen werden.
Dasselbe geschieht, wenn der Destruktor indirekt aufgerufen wird, z. B. delete base;
. Die delete
Die Anweisung ruft base->~Base()
die versandt werden an Derived::~Derived()
.
Abstrakte Klasse mit nicht-virtuellem Destruktor
Wenn Sie ein Objekt nicht über einen Zeiger auf seine Basisklasse löschen wollen, besteht keine Notwendigkeit für einen virtuellen Destruktor. Machen Sie es einfach protected
damit sie nicht versehentlich aufgerufen wird:
// library.hpp
struct Base {
virtual void f() = 0;
protected:
~Base() = default;
};
void CallsF(Base& base);
// CallsF is not going to own "base" (i.e. call "delete &base;").
// It will only call Base::f() so it doesn't need to access Base::~Base.
//-------------------
// application.cpp
struct Derived : Base {
void f() override { ... }
};
int main() {
Derived derived;
CallsF(derived);
// No need for virtual destructor here as well.
}