2017-03-21 3 views
1

Ich möchte ein Objekt der Klasse B zerstören.Aufruf der virtuellen Methode aus dem virtuellen Destruktor in C++

class A { 
public: 
    A() { 
     std::cout << "construct A" << av::endl; 
     a = new int; 
    } 
    virtual ~A() { 
     std::cout << "destruct A" << av::endl; 
     this->clear(); 
    } 
    virtual void clear() { 
     std::cout << "clear A" << av::endl; 
     delete a; 
    } 
protected: 
    int *a; 
}; 

class B : public A { 
public: 
    B() { 
     std::cout << "construct B" << av::endl; 
     b = new int; 
    } 
    ~B() { 
     std::cout << "destruct B" << av::endl; 
    } 
    void clear() override { 
     std::cout << "clear B" << av::endl; 
     delete b; 
     delete this->a; 
    } 
private: 
    int *b; 
}; 

Und ich will es mit clear() Verfahren durchgeführt werden. Aber wenn ich folgenden Code ausführen:

A *a = new B(); 
delete a; 

ich:

konstruieren Konstrukt B Destruct Destruct B eine klare A

Und clear B wird nie gedruckt. Was mache ich falsch?

Antwort

5

Informell, In ~A(); der B-Teil ist bereits zerstört, Aufruf einer Funktion von B macht keinen Sinn.


Wirksames C + + Item 9: Niemals virtuelle Funktionen während der Konstruktion oder Zerstörung aufrufen.

Sobald eine abgeleitete Klasse destructor ausgeführt wird, das abgeleiteten Klasse Datenelemente des Objekts übernehmen undefinierte Werte, so C++ behandelt sie, als ob sie keine mehr existieren. Nach dem Eintritt in den Basisklassendestruktor wird das Objekt zu einem Basisklassenobjekt, und alle Teile von C++ - virtuelle Funktionen, dynamic_cast s usw. - werden so behandelt.

+0

Danke für die Erwähnung von "Effective C++", ich denke, es ist Zeit für mich, es erneut zu durchlaufen. – StahlRat

Verwandte Themen