【C++】—— 智能指针

一、为什么需要智能指针

我们先来看一段代码

#include <iostream>
#include <vector>
#include <exception>
using namespace std;

void Test()
{
	int* tmp = (int*)malloc(sizeof(int)* 100);
	int* p = new int;
	
	vector<int> v1(1000000000, 10);
	vector<int> v2(10, 10);
	//v2[10] = 20;

		free(tmp);
		delete p;
}
int main()
{
	try
	{
		Test();
	}
	catch (const exception& e)
	{
		cout << e.what() << endl;
	}
	catch (...)
	{
		cout << "未知错误" << endl;
	}
	return 0;
}

智能指针
问题分析:上面的问题分析出来我们发现有以下两个问题?
1.由于抛出异常之后的跳转, malloc和new出来的空间,没有进行释放,存在内存泄漏的问题。
2. 异常安全问题。如果在malloc和free之间如果存在抛异常,那么还是有内存泄漏。这种问题就叫异常安全,异常介绍可参见博客 C++ 异常

二、智能指针的使用及原理

2.1 RAII

RAII(Resource Acquisition Is Initialization)是一种利用对象生命周期来控制程序资源(如内存、文件句柄、网络连接、互斥量等等)的简单技术。
在对象构造时获取资源,接着控制对资源的访问使之在对象的生命周期内始终保持有效,最后在对象析构的时候释放资源。借此,我们实际上把管理一份资源的责任托管给了一个对象。这种做法有两大好处:

  • 不需要显式地释放资源。
  • 采用这种方式,对象所需的资源在其生命期内始终保持有效。
//设计一个SmartPtr类
template<class T>
class SmartPtr
{
public:
	SmartPtr(T* ptr = nullptr)
		:_ptr(ptr)
	{}
	~SmartPtr()
	{
		if (_ptr)
			delete _ptr;
		cout << "~SmatrPtr()" << endl;
	}
private:
	T* _ptr;
};

void Test()
{
	int* tmp = (int*)malloc(sizeof(int)* 100);
	//将tmp指针委托给sp对象,让sp对象帮助tmp指针管理空间,直到tmp指针被销毁
	SmartPtr<int> sp(tmp);
	//vector<int> v(100000000, 10);
	string s = "程序出错";
	throw s;

	free(tmp);
}
int main()
{
	try
	{
		Test();
	}
	catch (string& s)
	{
		cout << s << endl;
	}
	catch (...)
	{
		cout << "未知错误" << endl;
	}
	return 0;
}

智能指针

  • 这里我们看到虽然在抛出异常后程序跳转至catch处,在抛出异常处后面的代码并未执行,但是由于将tmp的空间交给对象sp管理,在程序执行完之后,对象会自动调用析构函数清理资源,此时指针tmp的空间得到了正确的释放,这就是智能指针的用处。
  • 两种情况都会调用析构函数
  • 1、程序正常走完,出了作用域,sp对象被销毁调用析构函数清理资源
  • 2、程序抛出异常,跳出作用域到catch处,此时出了作用域sp对象被销毁调用析构函数清理资源

<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值