c++11新特性-智能指针

1. 智能指针的概念及原理


1.1 什么是智能指针

智能指针RAII(Resource Acquisition Is Initialization),是一种利用对象的生命周期来管理资源的技术。如果我们采用传统的new/delete来申请和释放资源,如果忘记调用delete,或者在调用delete之前程序抛出异常,都会导致内存泄漏问题,如代码1.1,Func函数中的new p2和Div都可能抛异常,导致后面的delete没有执行从而引发内存泄漏,采用智能指针对资源进行管理,能够杜绝这类问题。

代码1.1:因异常引发的内存泄漏

int Div(int a, int b)
{
   
	if (b == 0) {
   
        throw "除0错误";
    } else {
   
        return a / b;
    }
}
 
void Func()
{
   
	int* p1 = new int[5];
	int* p2 = new int[5];
 
	// 这里Div函数会抛异常,main函数会捕获异常,delete[]没有执行,引发内存泄漏
	int ret = Div(5, 0);
 
	delete[] p1;
	delete[] p2;
}
 
int main()
{
   
	try {
   
		Func();
	} catch (std::exception& e) {
   
		std::cout << e.what() << std::endl;
	} catch (...) {
   
		std::cout << "未知错误" << std::endl;
	}
 
	return 0;
}

智能指针是一个类,在对象构造时调用构造函数获取资源,在对象生命周期内,保证资源不被释放,在对象生命周期结束时,编译器自动调用析构函数来释放资源。这就相当于,将管理资源的责任移交给了对象,这样即使程序抛出异常也不存在内存泄漏,因为捕获异常往往跳出函数体,执行流会离开对象的作用域,对象生命周期结束,编译器自动调用析构函数释放了资源。

采用智能指针管理资源,有如下优点:
1> 将资源管理的责任转移给智能指针对象,不用显示地释放资源,杜绝了异常安全问题。
2> 保证对象管理的资源在其生命周期内有效。
代码1.2定义了一种简易的智能指针SmartPtr,在其析构函数中会对资源进行释放。因为申请的资源可能是通过new T、new T[n]、malloc(…)这几种方法的任意之一来申请的,每种方式申请的资源需要不同的关键字/函数来释放资源,否则程序可能会崩溃。

因此,需要一个模板参数Del,这个模板参数用于接收仿函数,以匹配不同的资源释放方式。我们默认采用delete的方式释放资源,C++标准库中提供的智能指针,如果不显示给定仿函数来定义释放资源的方式,也是默认delete释放资源。

代码1.2:智能指针的简易实现 – SmartPtr

template<class T>
struct Delete
{
   
	void operator()(T* ptr) {
    delete ptr;}
};
 
template<class T>
struct DeleteArray
{
   
	void operator()(T* ptr) {
    delete[] ptr; }
};
 
template<class T>
struct Free
{
   
	void operator()(T* ptr) {
    free(ptr); }
};
 
template<class T, class Del = Delete<T>>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

SuperYang_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值