181 Stimmen

Warum sollte ich einen virtuellen Destruktor für eine abstrakte Klasse in C++ deklarieren?

Ich weiß, dass es eine gute Praxis ist, virtuelle Destruktoren für Basisklassen in C++ zu deklarieren, aber ist es immer wichtig, die virtual Destruktoren auch für abstrakte Klassen, die als Schnittstellen fungieren? Bitte geben Sie einige Gründe und Beispiele an, warum.

5voto

JaredPar Punkte 699699

Das ist nicht nur eine gute Übung. Es ist die Regel Nr. 1 für jede Klassenhierarchie.

  1. Die Basisklasse einer Hierarchie in C++ muss einen virtuellen Destruktor haben

Und nun das Warum. Nehmen wir die typische Tierhierarchie. Virtuelle Destruktoren durchlaufen den virtuellen Versand wie jeder andere Methodenaufruf auch. Nehmen Sie das folgende Beispiel.

Animal* pAnimal = GetAnimal();
delete pAnimal;

Angenommen, Animal ist eine abstrakte Klasse. Die einzige Möglichkeit für C++, den richtigen Destruktor aufzurufen, ist über die virtuelle Methodenverteilung. Wenn der Destruktor nicht virtuell ist, wird er einfach den Destruktor von Animal aufrufen und keine Objekte in abgeleiteten Klassen zerstören.

Der Grund dafür, dass der Destruktor in der Basisklasse virtuell ist, besteht darin, dass die abgeleiteten Klassen nicht mehr die Wahl haben. Ihr Destruktor wird standardmäßig virtuell.

2 Stimmen

I meist mit Ihnen übereinstimmen, denn in der Regel Wenn Sie eine Hierarchie definieren, möchten Sie in der Lage sein, auf ein abgeleitetes Objekt zu verweisen, indem Sie einen Zeiger/Verweis auf die Basisklasse verwenden. Aber das ist nicht immer der Fall, und in diesen anderen Fällen kann es ausreichen, die Basisklasse dtor stattdessen zu schützen.

0 Stimmen

@j_random_hacker Eine geschützte Version schützt nicht vor falschen internen Löschungen.

1 Stimmen

@JaredPar: Das ist richtig, aber zumindest kann man in seinem eigenen Code verantwortlich sein - das Schwierige ist, sicherzustellen, dass Kundencode kann nicht dazu führen, dass Ihr Code explodiert. (In ähnlicher Weise verhindert die Privatisierung eines Datenelements nicht, dass interner Code etwas Dummes mit diesem Mitglied anstellt).

4voto

fatma.ekici Punkte 2657

Die Antwort ist einfach: Sie muss virtuell sein, sonst wäre die Basisklasse keine vollständige polymorphe Klasse.

    Base *ptr = new Derived();
    delete ptr; // Here the call order of destructors: first Derived then Base.

Sie würden die obige Löschung vorziehen, aber wenn der Destruktor der Basisklasse nicht virtuell ist, wird nur der Destruktor der Basisklasse aufgerufen und alle Daten in der abgeleiteten Klasse bleiben ungelöscht.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X