为什么析构函数要用虚析构:防止子类析构不被调用;防止在调用析构函数时崩溃。
例子如下:
#include <iostream> using namespace std;
class A { public: A() { cout << "A() ..." << endl; } virtual ~A() { cout << "~A() ..." << endl; } };
class B { public: B() { cout << "B() ..." << endl; } virtual ~B() { cout << "~B() ..." << endl; } };
class C: public A, public B { public: C() { cout << "C() ..." << endl; } ~C() { cout << "~C() ..." << endl; } };
void main() { // B* p = new C; // delete p;
/* A() ... B() ... C() ... ~B() ... 崩溃 */
// virtual ~A() // B* p = new C; // delete p;
/* A() ... B() ... C() ... ~B() ... 崩溃 */
// virtual ~B() // B* p = new C; // delete p;
/* A() ... B() ... C() ... ~C() ... ~B() ... ~A() ... */
// virtual ~A, ~B B* p = new C; delete p; /* A() ... B() ... C() ... ~C() ... ~B() ... ~A() ... */
return; }
|
#include <iostream> using namespace std;
class A { public: A() { cout << "A() ..." << endl; } virtual ~A() { cout << "~A() ..." << endl; } };
class B { public: B() { cout << "B() ..." << endl; } virtual ~B() { cout << "~B() ..." << endl; } };
class C: public A, public B { public: C() { cout << "C() ..." << endl; } ~C() { cout << "~C() ..." << endl; } };
void main() { // A* p = new C; // delete p;
/* A() ... B() ... C() ... ~A() ... */
// virtual ~A() // A* p = new C; // delete p; /* A() ... B() ... C() ... ~C() ... ~B() ... ~A() ... */
// virtual ~B() // A* p = new C; // delete p; /* A() ... B() ... C() ... ~A() ... 崩溃 */ // virtual ~A, ~B A* p = new C; delete p; /* A() ... B() ... C() ... ~C() ... ~B() ... ~A() ... */ return; }
|
总结:注意在定义基类时,必须将析构函数定义为虚析构,防止程序崩溃或子类对象析构不被调用的情况发生。