C++:RAII思想和智能指针(auto_ptr,unique_ptr,shared_ptr)

本文介绍了C++中的RAII思想及其在智能指针中的应用,详细阐述了auto_ptr、unique_ptr和shared_ptr三种智能指针的使用,包括它们的原理、优缺点及解决循环引用问题的方法。同时,讨论了智能指针在多线程环境下的线程安全问题,并展示了定制删除器的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有的时候使用malloc或者new创建的对象忘记释放就会导致内存泄漏,又或者此时释放语句之前有一段代码是抛异常的话,那么执行流就会乱跳,导致内存也无法释放。
比如这一段代码,at越界访问会导致抛异常,导致执行流跳出从而没有释放指针p。

void Func()
{
   
   
	int* p = new int;
	vector<int> v;
	v.at(0) = 10;//会抛异常
	delete p;//导致p没有释放
}

因此引入了智能指针来防止这种问题导致的内存泄漏。

RAII思想

智能指针的思想就是RAII,就是利用对象的生命周期来管控资源的一种方式。
在对象构造时获取资源,把资源交给对象管理,接着控制对资源的访问使之在对象的生命周期内始终保持有效,最后在对象析构的时候释放资源。实际上是把管理一份资源的责任托管给了一个对象。这种做法有两大好处:

  1. 不需要显式地释放资源。
  2. 采用这种方式,对象所需的资源在其生命期内始终保持有效。
智能指针的思想RAII(交给对象管理)
template<class T>
class SmartPtr
{
   
   
public:
	SmartPtr(T* ptr)
		:_ptr(ptr)
	{
   
   }
	~SmartPtr()
	{
   
   
		cout <<"delete:"<< _ptr << endl;
		delete _ptr;
	}
private:
	T* _ptr;
};

在对象的构造阶段把资源交给对象管理,对象的生命周期结束时会自动调用析构函数完成指针的释放。如图:抛出的异常被捕获,同时指针也释放了。
在这里插入图片描述

智能指针思想的变形(智能锁)

RAII思想可以扩展到锁上面,因为有时候加锁之后未解锁抛异常会导致执行流乱跳,而导致锁未释放,因此我们也可以基于此写一个智能锁,把这个锁交给一个对象管理,对象出了作用域就会自动调用析构函数完成锁的释放。但是这里需要注意的是,定义成员变量的时候要定义为引用,这样才能保证加锁的时候是加在同一个锁上的。

template<class T>//定义成模板就是如果有另外类型的锁来了也可以用这个SmartLock
class SmartLock
{
   
   
public:
	SmartLock(T& lock)
		:_lock(lock)
	{
   
   
		_lock.lock();
	}
	~SmartLock()
	{
   
   
		_lock.unlock();
	}
private:
	//使用引用就是为了保证加锁能加在同一个锁上面
	T& _lock;//引用定义变量就是在定义它的时候初始化它
};

使用如下:
smtlock管理了这个mtx,出了作用域会自动调smtlock的析构函数完成锁的释放。

void add(int n, int *value)
{
   
   
	SmartLock<mutex> smtlock(mtx);//用smtlock对象管理mtx这个锁,出了作用域会自动解锁
	for (int i = 0; i < n; i++)
	{
   
   
		++(*value);
	}
}
智能指针的两个要素
  1. RAII思想:把资源交给这个对象管理
  2. 能够像指针一样的行为(重载*->
template<class T>
class SmartPtr
{
   
   
public:
	//交给对象管理
	SmartPtr(T* ptr)
		:_ptr(ptr)
	{
   
   }
	~SmartPtr()
	{
   
   
		delete _ptr;
	}
	//像指针一样的行为
	T& operator*()//对象出了作用域还在,所以返回引用
	{
   
   
		return *_ptr;//返回这个对象
	}
	T* operator->()
	{
   
   
		return _ptr;//返回原生指针
	}
private:
	T* _ptr;
};

三种智能指针

1. auto_ptr(C++98)

C++98版本的库中提供了auto_ptr的智能指针。
想要实现一个智能指针就要实现这几个功能:RAII思想,像指针一样的行为。但是对象会有拷贝构造和赋值,auto_ptr的原理是进行了管理权的转移(管理权的转移就是,当把我的值给你之后,就把我置成空),这是一种带有缺陷的智能指针,会导致对象悬空

实现的原理如下:

template <class T>
class auto_ptr
{
   
   
public:
	auto_ptr(T* ptr)//构造
		:_ptr(ptr)
	{
   
   <
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值