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具有->和*运算符重载符,因此它可以像普通指针一样使用。
这是一种不好的编程风格,应该避免,因为它复杂而又容易出错。
#include#include using namespace std; class A {}; int main(){ A* ptrA = new A; try {//...//...//...//...//... } catch (...) {delete ptrA; //1throw; } delete ptrA; //2 return 0; }
【C++11智能指针unique_ptr用法使用场景分析】了解了这个痛点,那么本篇的主角unique_ptr就该闪亮登场了。
unique_ptr对象可以在自身被销毁时释放其所指向的数据。并且unique_ptr它所指向的对象只有一个拥有者。
上面糟心的代码就可以用unique_ptr来优化,在也不需要delete和catch子句。
#include#include using namespace std; class A {}; int main(){ unique_ptr upA(new A); //... //... return 0; }
四、unique_ptr的目的
- 获取某些资源
- 执行某些操作
- 将取得的资源释放掉
unique_ptrup1(new int(1)); //okunique_ptr up2 = new int(1); //error
构造函数1:可以用原始指针当实参传给构造函数。
但不能使用=赋值符,那样的话会报错,“无法从“int *”转换为“std::shared_ptr”,是不是很熟悉。
这点和share_ptr一致
构造函数2:make_unique函数
unique_ptr up4 = make_unique("hello"); //ok
构造函数3
int* p = new int; unique_ptrup5(p); //okunique_ptr up6(p); //logic error,这个是运行期错误,程序员必须避免这样的失误
这样的问题在于sp1,sp2,在丢失p的拥有权时释放相应资源,即会执行两次delete p操作。
不可以对unique_ptr执行copy或者assign操作,只能move,将拥有权移交给另一个unique_ptr
int* p = new int; unique_ptrup5(p); //ok unique_ptr up6(up5); //error unique_ptr up7(move(up5)); //ok
操作 | 效果 |
---|---|
unique_ptr up | Default构造函数,建立一个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 |
推荐阅读
- 人工智能|干货!人体姿态估计与运动预测
- ROOM1
- 从前沿科技到现实应用,人脸识别智能门禁加速走进智慧社区
- 众泰T500智能互联双加载,让汽车生活更有趣
- 历史上的今天|【历史上的今天】2 月 16 日(世界上第一个 BBS 诞生;中国计算机教育开端;IBM 机器人赢得智能竞赛)
- 【兔兔*亲子】八大智能启蒙之第三周记录
- 基于stm32智能风扇|基于stm32智能风扇_一款基于STM32的智能灭火机器人设计
- stm32|基于STM32和freeRTOS智能门锁设计方案
- 浅析(成人情趣用品智能无人自动售货机是新零售的下一个风口吗())
- Android智能手表MMI测试检测系统