C++11智能指针unique_ptr用法介绍

一、概述

C++ 标准模板库 STL(Standard Template Library) 一共给我们提供了四种智能指针:auto_ptr、unique_ptr、shared_ptr 和 weak_ptr,其中 auto_ptr 是 C++98 提出的,C++11 已将其摒弃,并提出了 unique_ptr 替代 auto_ptr。虽然 auto_ptr 已被摒弃,但在实际项目中仍可使用,但建议使用更加安全的 unique_ptr,后文会详细叙述。shared_ptr 和 weak_ptr 则是 C+11 从准标准库 Boost 中引入的两种智能指针。此外,Boost 库还提出了 boost::scoped_ptr、boost::scoped_array、boost::intrusive_ptr 等智能指针,虽然尚未得到 C++ 标准采纳,但是在开发实践中可以使用。

二、实现原理

  • unique_ptr 是 C++ 11 提供的用于防止内存泄漏的智能指针中的一种实现,即使在异常发生时也可帮助避免资源泄露。

  • unique_ptr实现了独享被管理对象指针的概念,这意味这它可确保一个对象和其对应的资源同一时间只被一个pointer拥有。一旦拥有者被销毁或者变成empty或者开始拥有另一个对象,先前拥有的那个对象就会被销毁,其任何相应资源亦会被释放。

  • unique_ptr具有->和*运算符重载符,因此它可以像普通指针一样使用。

三、使用场景

先看不使用智能指针,写代码时的痛点,有可能忘记delete对象,在某处return的时候,或者在某处抛出异常,导致末尾的delete语句就没机会被调用,导致内存泄漏。在还是只new一个对象,如果new2,3甚至更多对象,那管理起来,代码变的比较复杂,而且累赘。

这是一种不好的编程风格,应该避免,因为它复杂而又容易出错。

#include <memory>
#include<iostream>
using namespace std;

class A {};
int main()
{
	A* ptrA = new A;
	try
	{
		//...
		//...
		//...
		//...
		//...
	}
	catch (...)
	{
		delete ptrA;		//1
		throw;
	}

	delete ptrA;			//2
	return 0;
}

了解了这个痛点,那么本篇的主角unique_ptr就该闪亮登场了。

unique_ptr对象可以在自身被销毁时释放其所指向的数据。并且unique_ptr它所指向的对象只有一个拥有者。

上面糟心的代码就可以用unique_ptr来优化,在也不需要delete和catch子句。

#include <memory>
#include<iostream>
using namespace std;

class A {};
int main()
{
	unique_ptr<A> upA(new A);
	
	//...
	//...

	return 0;
}

四、unique_ptr的目的

  1. 获取某些资源
  2. 执行某些操作
  3. 将取得的资源释放掉

五、常用操作

unique_ptr<int> up1(new int(1));//ok
unique_ptr<int> up2 = new int(1);//error
  1. 构造函数1:可以用原始指针当实参传给构造函数。

    但不能使用=赋值符,那样的话会报错,“无法从“int *”转换为“std::shared_ptr”,是不是很熟悉。

    这点和share_ptr一致

  2. 构造函数2:make_unique函数

unique_ptr<string> up4 = make_unique<string>("hello");//ok
  1. 构造函数3
int* p = new int;
unique_ptr<int> up5(p);//ok
unique_ptr<int> up6(p);//logic error,这个是运行期错误,程序员必须避免这样的失误

这样的问题在于sp1,sp2,在丢失p的拥有权时释放相应资源,即会执行两次delete p操作。

不可以对unique_ptr执行copy或者assign操作,只能move,将拥有权移交给另一个unique_ptr

 	int* p = new int;
	unique_ptr<int> up5(p);//ok
	unique_ptr<int> up6(up5);//error
	unique_ptr<int> up7(move(up5));//ok
操作效果
unique_ptr upDefault构造函数,建立一个empty unique pointer
unique_ptr up(ptr)建立unique pointer令其拥有*ptr
unique_ptr up(nullptr)建立一个empty unique pointer
unique_ptr up(move(up2))建立一个unique pointer,拥有up2之前拥有的pointer(up2将为empty)
up.~unique_ptr()析构函数,调用deleter
up=up2赋值(sp将共享sp2的拥有权,放弃其先前索拥有对象的所有权)
up=move(up2)move assignment(sp2将拥有权移交给up)
up=nullptr对一个被拥有物调用delete,i并令为空(等价up.reset())
up1.swap(up2)==swap(up1,up2)交换up1,up2的pointer
up.reset()放弃拥有权,并重新初始化,使它=empty
up.reset(ptr)放弃拥有权,重新初始化(拥有*ptr)
make_unique(…)为一个新对象(以传入的实参为初值)建立一个unique pointer
up.get()返回存储的pointer,就是返回原始指针,对该原始指针如果执行delete,会异常。
*up同上
up->为拥有物提供成员访问
if(up)判断sp是否empty
get_deleter(up)返回deleter的地址(如果有的话),没有返回nullptr
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

苏克贝塔

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

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

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

打赏作者

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

抵扣说明:

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

余额充值