课程笔记:https://www.bilibili.com/video/BV1wx411473L?from=search&seid=11637211429638882354
为什么析构函数要是虚函数?
如果一个父类有子类,那么这个父类的析构函数一定是虚析构函数,原因是:
如果父类的析构函数不是虚析构,那么当用delete删除一个指向子类对象的父类指针时,将调用父类的析构函数,子类只释放了来自父类的那部分成员变量,而子类自己扩展的成员没有被释放,造成内存泄露。在下图中可以看到,我们在堆上申请了一个子类的对象,并用父类的指针指向这个对象,当delete该父类指针时,却只调用了父类的析构函数!子类的空间并没有被释放。
当我们为父类的析构函数加上virtual关键字之后,delete B先调用了子类的析构函数,释放子类成员所占用的空间,然后调用父类的析构函数,释放了父类所占用的空间。
最后要讨论一下,为什么构造函数不能是虚函数 ,理由是:
在编译阶段,编译器会在类中添加一个看不见的成员,即虚函数表指针,并在构造函数中对虚函数表指针进行初始化,通过虚函数表指针才能够找到虚函数表,进而实现不同虚函数的调用,因此在执行构造函数之前,编译器并不知道虚函数表的初始值是谁,更不可能成功编译本虚构造函数!