本章节就在强调一件事情,如果一个类是基类,且用于多态,那么该base class的析构函数,要写成virtual 的。如果其不是base class 或不用于多态就不要用virtual析构了。
注:多态就是基类指针指向子类对象。
可这是为什么呢?
若
class TimeKeeper{
public:
TimeKeeper();
~TimeKeeper();
.....
};
class AtomicClock:public TimeKeeper{....}; //原子钟
class WaterClock:public TimeKeeper{....}; //水钟
class WristWatch:public TimeKeeper{....}; //腕表
有时只是想知道时间,不去理会通过什么得到的时间那么
TimeKeeper *getTimeKeeper();//该函数返回一个指针,指向一个子类对象,如return AtomicClock *ac;
TimeKeeper *ptk=getTimeKeeper();
...
delete ptk;
那么现在就是一个子类对象经由一个基类指针删除delete。这就会发生问题,会造成局部销毁。对象 内的AtomicClock成分可能没有被销毁,而base class部分被销毁了。
只要 将基类的析构函数改为 virtual ~TimeKeeper();即可。因为virtual允许子类的实现得以客制化。
在这章节提到了新概念,虚拟函数表也就是说若一个类含有virtual函数,那么其对象成分中就会含有一个指针vptr,指向这个虚拟函数表vbtl,这个vbtl就是一个函数指针构成的数值,这些指针指向虚拟函数。注vbtl[0]指向的是类型信息,对此要详细了解可以看看“深度探索C++对象模型”讲的很好。
本章节还强调一点:不要无端的将所有class的析构函数声明为virtual。原因1、增加对象大小,2、与其他语言的结构不同(如C,其没有vbtl),不便移植。
当然那些不用于多态的基类,也不要声明为析构为virtural,没有意义。