条款07:为多态基类声明virtual析构函数
当派生类对象通过基类指针删除,而基类的析构函数是非虚函数。那么,对象的基类部分会销毁,而派生类部分没有被销毁。解决该问题的方法是给基类一个虚析构函数。
#include <iostream> #include <string> using namespace std; class FileSys { public: void doSomething(){ cout << "doSomething in base class" << endl; } ~FileSys(){ cout << "Destructor in base class" << endl; } }; class WinFileSys: public FileSys { public: void doSomething(){ cout << "doSomething in Derived class" << endl; } ~WinFileSys() { cout << "Destructor in Derived class" << endl; } }; int main(){ FileSys *p = new WinFileSys; //基类指针,指向派生类对象 p->doSomething(); //实际调用了基类的函数 delete p; system("pause"); return 0; }运行结果
doSomething in base class Destructor in base class上例中通过基类指针p删除派生类对象,但是由于基类FileSys的析构函数是非虚函数,执行结果未定义。实际执行中,对象的基类部分被销毁,派生类部分没有被销毁,形成“局部销毁”的现象。
解决上述问题的方法是:基类FileSys的析构函数定义为虚函数。此时通过基类指针p删除派生类对象,会销毁整个对象。
#include <iostream> #include <string> using namespace std; class FileSys { public: virtual void doSomething(){ cout << "doSomething in base class" << endl; } //虚函数 virtual ~FileSys(){ cout << "Destructor in base class" << endl; } //虚函数 }; class WinFileSys: public FileSys { public: void doSomething(){ cout << "doSomething in Derived class" << endl; } ~WinFileSys() { cout << "Destructor in Derived class" << endl; } }; int main(){ FileSys *p = new WinFileSys; p->doSomething(); delete p; system("pause"); return 0; }运行结果
doSomething in Derived class Destructor in Derived class Destructor in base class
总结
- 带多态性质的基类应该声明一个virtual析构函数。此时可以通过基类接口处理派生类对象。
- class带有任何virtual函数,它就应该拥有一个virtual析构函数。
- class不作为基类使用,不具备多态性质,就不该声明virtual析构函数。