本文解答为什么要将一个基类的虚构声明为虚析构
实际上在谈到基类的概念时,我们默认这个类是会被继承的,这样才有子类继承基类这一种说法嘛。对于一般的类,并不要求将其虚构函数写成虚析构,因为当用“virtual”关键字修饰一个函数时,系统默认为该类维护(创建)一个虚表(装有虚函数地址的一维数组),创建该类的对象时,取对象内存单元的前四个字节,我们称之为子类的虚指针(这里是32位系统,指针类型大小为4B),将指向这个虚表的入口地址。而虚表和虚指针的定义是消耗系统内存的,我们并不希望产生这些额外开销,所以一般在需要使用子类多态时才会考虑设置成虚析构。
那么将父类的析构函数变为虚析构是否必要,请看代码测试结果:
#include<iostream>
using namespace std;
class CBase
{
public:
CBase()
{
cout << "CBase()" << endl;
}
~CBase()
{
cout << "~CBase()" << endl;
}
};
class CDeriveA : public CBase
{
public:
CDeriveA()
{
cout << "CDerive()" << endl;
}
~CDeriveA()
{
cout << "~CDerive()" << endl;
}
};
int main()
{
CBase *pA = new CDeriveA();
delete pA;
return 0;
}
这里我们可以看到,只执行了父类的虚构,没有执行子类虚构,将导致派生类对象无法销毁,即内存泄漏 问题。
那么如果改为虚析构呢?
此次执行基类的析构之前,先执行了派生类的析构,即先完成派生类对象成员的回收,再回收基类的对象成员。
因为讲虚析构不得不涉及多态的问题,不明白多态机制的小伙伴可能还是会有些糊涂,那希望弄明白C++三大特性之一的多态之后,再来看这个,相信会容易很多。
ps:多态是一块很重要的内容,不论是面试还是学习做开发都是重中之重!
哪里有问题还请大家在评论区留言呐~