[原创文章欢迎转载,但请保留作者信息]
Justin 于 2009-11-02
vczh同学建议发布随笔的时候选择首页,不知合不合适,我先试试看,要是有不对的地方,还请指点:)
从Item7开始讲析构函数(Destructor)。
将析构函数定义为虚函数(virtual function)是必须要提的。(是不是需要一个虚函数的笔记?)
在一个多态(Polymorphic)的继承体系中,基类(base class)的析构函数应该定义为虚函数。否则在通过基类指针析构一个子类对象的时候,因为没有虚表(V Table)对析构函数的指引,对象的基类部分是被毁了,对象的子类部分却没办法得到析构(没有了虚表中的说明它根本不知道有子类的析构函数来析构子类部分!),从而导致内存泄漏。
我想炒冷饭系列应该以举例为特色……好吧,我就姑且来胡乱举个例子:
假设基类指针在析构时要做的事情是奉命救人:指针啊指针,XX地发大水了,你赶紧去把张三一家人(子类对象)救出来。
指针拿着指令(析构函数)就找到了张三(张三家家长,子类对象的基类部分):张三是吧,你一家人都在这里了吧,跟我走吧。(析构吧,回空余内存里去吧@#¥%)
如果张三已经没有其他亲戚了,他就是张三家的全部人(这个对象其实就是基类对象)。很简单,直接跟着指针走就完事了。
如果张三还有个小弟叫张三疯(张三家除张三外的一部分,即子类对象的子类部分),张三就必须拿着族谱(V Table)跟指针说哎呀这是我弟啊,把他也析构了吧,张三家对您感恩不尽……也很简单,一并带走就完成任务了(完整析构/释放了整个对象)
如果,张三没了族谱,记不得有个张三疯弟弟,傻乎乎的跟了指针走,大家也以为张三一家都被救出来了。灾区里就只剩下张三疯一个人在疯跑了(memory leak)
另一方面,如果不准备把某个类用作多态中的基类,就没必要定义析构函数为虚函数。这样除了增加代码大小开销外(因为需要空间存放虚表),没有任何好处。(这个倒是很多书上没说过的)
如果张三家本来就只有张三一个人,他就没必要还要带着个空白的族谱了。逃命的时候能扔就扔嘛。
最后提到的一点和抽象类有关。抽象类是有纯虚函数的类,只能作为接口,不能有自己的对象。在设计软件框架的时候会有需要用到抽象类的时候。可是如果有这么一个类,需要设计为抽象类,但是却找不到一个成员函数可以拉去做纯虚函数,那么这个时候就把析构函数定义为纯虚函数好了。只是同时还要给它一个空的实现。
class::~class() {}
这种情况应该还是有的,只是我现在却想象不出来……那就先死记着咯~