关于虚析构函数的调用问题
关于虚析构函数的调用问题,情景如下:ClassCBase;ClassCExtendpublicCBase;在main中做如下处理CBase*pBase=newCExten...
关于虚析构函数的调用问题,情景如下:
Class CBase;
Class CExtend public CBase;
在main中做如下处理
CBase *pBase = new CExtend;
delete pBase;
对于基类的析构函数是虚函数的情况下,
父类和子类的析构函数都将得到执行,也就是说
两个类都安全地释放了资源;但是如果析构函数
不是虚析构函数,那么只有基类的析构函数得到
执行,请问这是为什么? 展开
Class CBase;
Class CExtend public CBase;
在main中做如下处理
CBase *pBase = new CExtend;
delete pBase;
对于基类的析构函数是虚函数的情况下,
父类和子类的析构函数都将得到执行,也就是说
两个类都安全地释放了资源;但是如果析构函数
不是虚析构函数,那么只有基类的析构函数得到
执行,请问这是为什么? 展开
2个回答
展开全部
虚函数存放在类的虚表中,虚函数的调用如果不是显示调用的话,默认是调用子类的虚函数。
当基类的析构函数是虚函数的时候,子类继承基类的虚函数,所以子类的析构函数也是虚函数。
如上面的例子,虽然new CExtend赋值给了CBase *PBase,但当调用delete pBase时,由于虚函数的动态关联,首先调用的是子类中的析构函数。当子类析构函数执行完毕后,子类所占用的内存,相对于父类多出的内存就已经得到完全释放了(注:子类的析构函数结束之前完成了子类自己的资源的释放)。此时,子类被释放了,就不会再有子类存在了,所以将会继续调用基类中的析构函数,来继续执行。
而当析构函数不是虚函数的时候,就不会有动态关联的功能。由于pBase的类型是CBase,所以就相当于显示调用了基类中的CBase的析构函数,而子类中的析构函数却没有被调用,如果自类中有自己的在“堆”上开辟的空间的话,而恰好是在子类的析构函数中完成内存回收的话,这样就会因为没有执行到子类的析构函数,而导致内存泄漏。
然而,对于子类中没有任何在“堆”上申请的空间的话,析构函数是否为虚函数,都将不会产生内存泄漏。
当基类的析构函数是虚函数的时候,子类继承基类的虚函数,所以子类的析构函数也是虚函数。
如上面的例子,虽然new CExtend赋值给了CBase *PBase,但当调用delete pBase时,由于虚函数的动态关联,首先调用的是子类中的析构函数。当子类析构函数执行完毕后,子类所占用的内存,相对于父类多出的内存就已经得到完全释放了(注:子类的析构函数结束之前完成了子类自己的资源的释放)。此时,子类被释放了,就不会再有子类存在了,所以将会继续调用基类中的析构函数,来继续执行。
而当析构函数不是虚函数的时候,就不会有动态关联的功能。由于pBase的类型是CBase,所以就相当于显示调用了基类中的CBase的析构函数,而子类中的析构函数却没有被调用,如果自类中有自己的在“堆”上开辟的空间的话,而恰好是在子类的析构函数中完成内存回收的话,这样就会因为没有执行到子类的析构函数,而导致内存泄漏。
然而,对于子类中没有任何在“堆”上申请的空间的话,析构函数是否为虚函数,都将不会产生内存泄漏。
光点科技
2023-08-15 广告
2023-08-15 广告
通常情况下,我们会按照结构模型把系统产生的数据分为三种类型:结构化数据、半结构化数据和非结构化数据。结构化数据,即行数据,是存储在数据库里,可以用二维表结构来逻辑表达实现的数据。最常见的就是数字数据和文本数据,它们可以某种标准格式存在于文件...
点击进入详情页
本回答由光点科技提供
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询