一个函数的返回值为基类指针,而当指针指向一个派生类对象,接下来派生类对象被这个基类指针删除的时候,就出现了局部销毁的问题。因为C++指出,当派生类经由一个基类指针被删除,而该基类指针带着一个non-virtual析构函数,其结果未有定义。实际的执行情况是派生类的析构函数没有执行,然而基类的成分通常会被销毁,于是早晨了诡异的“局部销毁”对象。这是造成资源泄漏、败坏数据结构、在调试器上浪费许多时间的绝佳途径==。
给基类一个virtual析构函数就可以消除这个问题了。
如果基类不含virtual函数,通常表示它并不意图被用做一个基类,当class不企图被当作基类时,令其析构函数为virtual往往是个馊主意。某些不带virtual函数的小型类本可以当作参数传给C语言的函数,但是如果把析构函数变成virtual,会增加类的大小,因为有了虚函数,类会有vtbl(virtual table虚函数表),一个 由函数指针组成的数组,这个函数指针是vptr(virtual
table pointer)指针,在运行期指出哪一个virtual函数该被调用。
有时候令class带一个pure virtual析构函数(纯虚析构函数)可能会带来一些便利。纯虚函数导致抽象类,不能被实体化。有时候希望拥有抽象类,但没有纯虚函数,策略就是:为你希望它成为抽象类的哪个class声明一个纯虚析构函数;还有一点注意就是要给这个纯虚析构函数一个定义,因为析构函数的运作方式是最深层派生的类的析构函数最先被调用,然后每一个基类的析构函数被调用。编译器会在派生类的析构函数中创建一个对抽象基类析构函数的调用动作,所以你必须为这个函数提供一份定义。
总结:
1、polymorphic(带多态性质的)基类应该声明一个virtual析构函数。如果class带有任何virtual函数,它就应该拥有一个virtual析构函数。
2、Calsses的设计目的不是作为基类使用(例如标准string和STL容器),或不是为了具备多态性(polymorphically),就不该声明virtual析构函数。