一、为什么需要虚析构函数?
书中举了一个TimeKeeper,一个关于时间的类来说明问题。要回答这个问题,首先要讨论c++的多态机制,多态是通过基类的指针或引用去操作派生类,而客户与抽象的基类打交道,而真正具体调用哪个类的方法,实现,都是在运行时确定(晚绑定)。关键在于,我们使用基类的指针或者引用去操作派生类,如果我们去delete一个基类的指针,如果指针是指向一个基类的对象,那没有任何问题。如果基类是指向一个派生类对象呢?在标准c++中这将未定义的行为。而具体会发生什么,我认为要看编译器怎么实现,一般来说这将导致基类部分被destroy,而派生类部分依然存在,这时就产生了内存泄露。而这样的错误经常是很难被发现的。
二、总是把析构函数定义为虚有事可能是个坏主意。
回到一中的讨论,都是在多态的前提下讨论。那如果我们的类并不打算作为一个基类使用和使用多态,虚函数还应该是虚的么?答案当然是:NO!!!
书本通过一个Point,二维坐标来说明。明显对于Point,我们设计的初衷只是把它当做一个结构体来使用,并不打算发展继承层次。其实对于这个问题自己并没有如此之理解,特别是书中提到的移植性问题,没处理过这个问题,也没有这个概念。大致是说,由于虚函数的实现需要保存一个指向虚表虚指针,这使得类膨胀,分别在32位和64位凶环境下进行了讨论,得出的结论是这样会使这个Point类的体积膨胀50%-100%。通常系统会把这个Point对象放到64位的寄存器里面,而在膨胀之后就放不下了,需要做其他额外的工作,影响了效率。在移植性方面,因为其他语言例如:c什么的,是没有虚机制的,也就是没有虚指针,我们就不能把这个类当做struct来使用传给c编写的接口。
三、在使用别人的类库时也应该注意,类是不是有一个虚析构函数!
即使我们明白了徐析构函数的作用,没有虚析构函数的类还是会给我们造成麻烦,那就是在使用别人提供的类库时,试图图从其中派生自己的类!对于STL所有的诸如Sting,map,set,vector....都没有虚析构函数,如果试图从其中派生自己的类就会出现问题。effective c++提到:遗憾的是c++并没有提供一种类似于java,c#拥有的机制去防止这种情况。我们所能做的只有告诉自己别这样做。
The End~~~~~~
找工作很累,身心都,但相信总会见彩虹的