2016-04-01 9 views
0

Ich habe ein paar andere ähnliche Fragen zu dem Thema gelesen, aber ich bin immer noch verwirrt über die Verwendung von Löschen für dynamisch zugewiesenen Speicher und virtuellen Destruktoren. Wenn ich ein Objekt der Klasse Base oder der Klasse Derived in einer verknüpften Struktur habe, so dass, wenn ich einen Knoten lösche, ich auch alle Knoten löschen möchte, die diesen Knoten einen Vorfahren nennen können. Muss ich dies im Destruktor angeben, wie unten gezeigt? Oder wird sich die Verwendung eines virtuellen Destruktors ohne die beiden delete s schon darum kümmern?Virtuelle Destruktoren und löschen Schlüsselwort

class Base{ /*...*/ }; 

class Derived: public Base 
{ 
    public: 
     //various virtual functions// 
     virtual ~Derived() 
     { 
      delete leftPtr; 
      delete rightPtr; 
     } 
    private: 
     Base* leftPtr = new Derived(); 
     Base* rightPtr = new Derived(); 
}; 
+0

Es ist wenig sinnvoll, einen 'virtuellen' Destruktor zu verwenden, wenn Sie keine virtuellen Methoden haben, oder wenn der' Base'-Destruktor nicht 'virtuell' ist –

+0

Dies ist nicht nahe am Kompilieren. 'Base * p = neu abgeleitet;' wird nie funktionieren. –

+0

Dies setzt voraus, dass der Destruktor der Basisklasse der Basis virtuell ist und es verschiedene virtuelle Methoden gibt. Sollte geklärt haben. – LBaelish

Antwort

2

Oder wird die Verwendung eines virtuellen destructor ohne die beiden Löschungen dies bereits kümmern?

Mit einem virtuellen Destruktor wird nicht gelöscht leftPtr und righPtr gelöscht. Ein virtueller Destruktor stellt sicher, dass der Destruktor, der den meisten abgeleiteten Objekten entspricht, auch dann aufgerufen wird, wenn delete für einen Basisklassenzeiger verwendet wird.

Sie haben nicht gezeigt, dass Base einen virtuellen Destruktor hat. Unter der Annahme, es tut,

Derived* ptr1 = new Derived; 
delete ptr1; // Calls ~Derived() 

Base* ptr2 = new Derived; 
delete ptr2; // Also calls ~Derived() 

Wenn Sie jedoch

weggelassen
delete leftPtr; 
delete rightPtr; 

von Derived::~Derived(), wird Ihr Code ein Speicherleck.

+0

Ich denke, er könnte Gefahr laufen, mit delete leftPtr doppelt zu löschen und rightPtr zu löschen. Intelligente Zeiger wären die beste Option. – MIbrah

+0

Ok, ich verstehe was du sagst. Sagen wir, ich wollte nicht löschen, was links und rechts ist. Angenommen, ich habe eine mehrfach verknüpfte Struktur und was auch immer links und rechts ist, wird auch von anderen Objekten angezeigt. In diesem Fall würde ich die beiden Löschanweisungen korrekt auslassen? Und kein Schaden angerichtet? – LBaelish

+0

@LBaelish, müssen Sie eine Möglichkeit finden, alles zu löschen, das vom Heap zugewiesen wird. Wenn mehrere Objekte auf ein Objekt zeigen können, verwenden Sie am besten 'std :: shared_ptr'. Andernfalls benötigen Sie eine Menge Buchhaltungscode, um die Zeiger zu verwalten, was 'std :: shared_ptr' bereits tut. –