c++虚析构和纯虚析构

本文围绕C++的虚析构和纯虚析构展开。指出多态使用时,若子类有堆区属性,父类指针释放无法调用子类析构代码,会造成内存泄漏。将父类析构函数设为虚析构或纯虚析构可解决该问题,还介绍了二者共性、区别及使用场景。

c++中不能声明构造函数,但是可以声明虚析构函数和纯虚析构函数。

 

虚析构和纯虚析构

纯虚析构的使用场景:多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码。(1.父类指针指向子类对象,2.子类在堆区有数据)

解决方式:将父类中的析构函数改为虚析构或者纯虚析构

虚析构和纯虚析构共性:

  • 可以解决父类指针释放子类对象
  • 都需要有具体的函数实现

虚析构和纯虚析构区别:

  • 如果是纯虚析构,该类属于抽象类,无法实例化对象

虚析构语法:

virtual ~类名(){}

纯虚析构语法:

virtual ~类名() = 0;

类名::~类名(){}

示例:

一:我们先不设置为虚函数:

#include<iostream>
using namespace std;
class base {
public:
	~base() {
		cout << "父类析构函数被调用" << endl;
	}
};
class derived :public base{
public:
	int* p;
	derived() {
		p = new int(2);
	}
	~derived() {
		cout << "子类的析构函数被调用" << endl;
		delete p;
	}
};
void fun(base* ptr) { //fun函数把传入的指针p指向的堆区数据给释放掉
	delete ptr;
}
int main() {
	base* b = new derived();
	fun(b);
	return 0;
}

这个说明,通过基类指针删除派生类对象的时候调用的是基类的析构函数,但是我子类的析构函数却没有被调用,这样就造成了子类动态分配的内存无法释放掉,造成了内存泄漏。也就是说派生类对象成员p所指向的内存空间,在对象消亡之后既不能被本程序继续使用,也么有被释放掉。对于内存需求量大,长时间连续运行的大程序来讲,这样会浪费相当多的内存,相当危险,所有如果子类有动态内存分配,一定要把基类的析构函数设置为虚函数。

 

二:当我们把父类的析构函数设置为虚函数之后,

virtual ~base() {
        cout << "父类析构函数被调用" << endl;
    }

可以看出:

当把父类的析构函数设置为析构函数之后,就可以调用子类的析构函数,这样就可以把子类创建的堆区数据给释放掉。 

 因为  C++明确指出,当子类对象经由一个父类指针被删除,而该父类带有一个non-virtual析构函数,其结果未定义--实际执行时通常发生的是对象的derived成分没有被销毁。子类的析构函数也未能被执行。这就造成了内存泄漏的危险。

 

总结:

​ 1. 虚析构或纯虚析构就是用来解决通过父类指针释放子类对象

​ 2. 如果子类中没有堆区数据,可以不写为虚析构或纯虚析构

​ 3. 拥有纯虚析构函数的类也属于抽象类

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ad_m1n

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值