2016-09-20 6 views
0
#include <iostream> 
using namesapce std; 
class A 
{ 
    public: 
     virtual ~A(){cout<<"delete A"<<endl}; 
}; 
class B: public A 
{ 
    public: 
     B(int n):n(n){} 
     void show(){cout<<n<<endl;} 
     ~B(){cout<<"delete B"<<endl;} 
    private: 
     int n; 

} 
int main() 
{ 
    A *pa; 
    B *pb = new B(1); 
    pa = pb; 
    delete pa; 
    pb->show(); 
    return 0; 
} 

wenn destructor von calss A virtual ~A(){...}, die Ausgabe des Programms: delete B delete A 1 wenn destructor der Klasse A ist ~A(){...}, dessen Ausgang progarm: delete A 0 , warum der Wert von n verschieden ist, wenn Destruktor der Klasse A ist virtuell oder nicht virtuell? Wenn Call Destruktor von B zu zerstören Objekt, warum das Calss Mitglied n ist noch existent?Warum hat das Calss-Member n von B einen anderen Wert, wenn der Destruktor der Klasse A virtuell oder nicht virtuell ist?

+0

Verstehen Sie, was eine 'virtuelle' Funktion ist? – Barry

+1

Was ist 'pb-> show() {};'? – AnT

+0

Sie können dies lesen http://www.learncpp.com/cpp-tutorial/122-virtual-functions/ –

Antwort

1
A *pa; 
B *pb = new B(1); 
pa = pb; 

Dies wird Upcasting genannt. Wenn Upcasting durchgeführt wird, sollte der Destruktor der Basisklasse virtuell gemacht werden.

Ohne virtuelles Basisdestructor ruft delete pa nur den Destruktor der Basisklasse auf, was unerwünscht ist, weil das abgeleitete Klassenobjekt niemals zerstört wird und zu einem Speicherleck führt.

Der virtuelle Destruktor der Basisklasse ruft zuerst den abgeleiteten Klassendestruktor auf und dann wird er sich selbst zerstören, was das gewünschte Verhalten ist und wegen Upcasting kein Leck verursacht.

+0

Kurz gesagt, ohne eine virtuelle Basisklasse Destruktor, erhalten Sie _undefined Behavior_. – qxz

+0

Warum ist der Wert von n anders? – PengWin

+0

was ist undefiniertes Verhalten, warum Compiler Tell Coder gibt es einen Fehler? – PengWin

1

Ihr Programm weist ein undefiniertes Verhalten auf. Das ist die einzige Antwort auf Ihre Frage "Warum".

Erstens, wenn der Destruktor A nicht virtuell ist, führt das Ausführen von delete pa in Ihrem Code zu undefiniertem Verhalten. Trying zu delete Objekt des Typs B durch einen Zeiger auf den übergeordneten Typ A * führt zu undefiniertem Verhalten des Destruktors von A ist nicht virtuell.

Zweitens scheint pb->show() ein Versuch zu sein, eine Methode eines bereits zerstörten Objekts aufzurufen. Das Verhalten ist auch nicht definiert, unabhängig davon, ob Destruktoren virtuell sind oder nicht.

Verwandte Themen