在使用多态机制的时候,会将一个基类指针指向派生类对象。这时,如果通过基类指针来删除这个对象,并且基类的析构函数不是虚函数,则这个对象只有其中的基类部分被析构,其余部分仍然保留,进而容易造成资源泄露的问题。
因此,使用到多态的基类的析构函数应该声明为虚函数。
如果一个类中有虚函数,那么应该有某个派生类继承它并实现相应的虚函数,进而实现多态机制,所以这种情况下基类的析构函数应该声明为虚函数。
如果一个类不包含任何虚函数,那通常意味着这个类不会被用作基类,这时候将其析构函数声明为虚函数通常是不可取的,有以下坏处:
- 虚函数的实现需要为每个类维护一张虚函数表以及相应的虚函数指针,这会使得类的占用空间变大
- 增加了不必要的虚函数之后,这样的类不再能够兼容到C等其他不支持虚函数的语言中
总之,不讲武德地将所有析构函数都声明为虚函数,和从来不这样做,一样都是大错特错。
当且仅当类中有至少一个虚函数时,才将析构函数声明为虚函数。
标准库中的string
、各种STL容器比如vector
、list
、set
以及tr1::unordered_map
等等,它们的析构函数都不是虚函数,不可以去继承它们。
如果要定义一个没有普通纯虚函数的抽象类,可以定义一个纯虚析构函数。
由于子类析构函数会调用基类析构函数,虽然基类析构函数是纯虚函数,但还是要补上一个空的定义。
- 多态基类应声明虚析构函数。如果一个类中有虚函数,那它的析构函数也应该是虚函数。
- 不被设计成基类、或者不被设计成用于多态的类,不应该使用虚析构函数。