参考链接

  • std::unique_ptr

介绍

  • 定义位于头文件<memory>
  • std::unique_ptr 是通过指针占有并管理另一对象,并在 unique_ptr 离开作用域时释放该对象的智能指针。 在下列两者之一发生时用关联的删除器释放对象:1,销毁了管理的 unique_ptr 对象;2, 通过 operator= 或 reset() 赋值另一指针给管理的 unique_ptr 对象。
  • 通过调用 get_deleter()(ptr) ,用潜在为用户提供的删除器释放对象。默认删除器用 delete 运算符,它销毁对象并解分配内存。
  • unique_ptr 亦可以不占有对象,该情况下称它为空 (empty)。 std::unique_ptr 有两个版本: 1) 管理单个对象(例如以 new 分配) 2) 管理动态分配的对象数组(例如以 new[] 分配)
  • 类满足可移动构造 (MoveConstructible) 和可移动赋值 (MoveAssignable) 的要求,但不满足可复制构造 (CopyConstructible) 或可复制赋值 (CopyAssignable) 的要求。
  • 只有非 const 的 unique_ptr 能转移被管理对象的所有权给另一 unique_ptr 。若对象的生存期为 const std::unique_ptr 所管理,则它被限定在创建指针的作用域中。
  • std::unique_ptr 常用于管理对象的生存期,包含:
  • 通过正常退出和经由异常退出两者上的受保证删除,提供异常安全,给处理拥有动态生存期的对象的类和函数
  • 传递独占的拥有动态生存期的对象的所有权到函数
  • 从函数获得独占的拥有动态生存期对象的所有权
  • 作为具移动容器的元素类型,例如保有指向动态分配对象的指针的 std::vector (例如,若想要多态行为)
  • std::unique_ptr 可为不完整类型 T 构造,例如用于改善用作 pImpl 手法中柄的用途。若使用默认删除器,则 T 必须在代码中调用删除器点处完整,这发生于析构函数、移动赋值运算符和 std::unique_ptr 的 reset 成员函数中。(相反地, std::shared_ptr 不能从指向不完整类型的裸指针构造,但可于 T 不完整处销毁)。注意若 T 是类模板特化,则以 unique_ptr 为运算数的使用,如 !p ,因 ADL 而要求 T 的形参完整。
  • 若 T 是某基类 B 的派生类,则 std::unique_ptr<T> 可隐式转换为 std::unique_ptr<B>。产生的 std::unique_ptr<B> 的默认删除器将使用 B 的 operator delete ,这导致未定义行为,除非 B 的析构函数为虚。注意 std::shared_ptr 表现有别: std::shared_ptr<B> 将使用类型 T 的 operator delete ,而且即使 B 的析构函数非虚,也会正确删除被占有对象。
  • 不同于 std::shared_ptr , std::unique_ptr 可通过任何满足可空指针 (NullablePointer) 的定制柄类型管理对象。例如,这允许管理位于共享内存,但提供定义 typedef boost::offset_ptr pointer; 或其他缀饰指针的 Deleter 的对象。

参考代码

#include <iostream>
#include <vector>
#include <memory>
#include <cstdio>
#include <fstream>
#include <cassert>
#include <functional>struct B {virtual void bar() { std::cout << "B::bar\n"; }virtual ~B() = default;
};
struct D : B
{D() { std::cout << "D::D\n";  }~D() { std::cout << "D::~D\n";  }void bar() override { std::cout << "D::bar\n";  }
};// 消费 unique_ptr 的函数能以值或以右值引用接收它
std::unique_ptr<D> pass_through(std::unique_ptr<D> p)
{p->bar();return p;
}void close_file(std::FILE* fp) { std::fclose(fp); }int main()
{std::cout << "unique ownership semantics demo\n";{auto p = std::make_unique<D>(); // p 是占有 D 的 unique_ptrauto q = pass_through(std::move(p)); assert(!p); // 现在 p 不占有任何内容并保有空指针q->bar();   // 而 q 占有 D 对象} // ~D 调用于此std::cout << "Runtime polymorphism demo\n";{std::unique_ptr<B> p = std::make_unique<D>(); // p 是占有 D 的 unique_ptr// 作为指向基类的指针p->bar(); // 虚派发std::vector<std::unique_ptr<B>> v;  // unique_ptr 能存储于容器v.push_back(std::make_unique<D>());v.push_back(std::move(p));v.emplace_back(new D);for(auto& p: v) p->bar(); // 虚派发} // ~D called 3 timesstd::cout << "Custom deleter demo\n";std::ofstream("demo.txt") << 'x'; // 准备要读的文件{std::unique_ptr<std::FILE, void (*)(std::FILE*) > fp(std::fopen("demo.txt", "r"),close_file);if(fp) // fopen 可以打开失败;该情况下 fp 保有空指针std::cout << (char)std::fgetc(fp.get()) << '\n';} // fclose() 调用于此,但仅若 FILE* 不是空指针// (即 fopen 成功)std::cout << "Custom lambda-expression deleter demo\n";{std::unique_ptr<D, std::function<void(D*)>> p(new D, [](D* ptr){std::cout << "destroying from a custom deleter...\n";delete ptr;});  // p 占有 Dp->bar();} // 调用上述 lambda 并销毁 Dstd::cout << "Array form of unique_ptr demo\n";{std::unique_ptr<D[]> p{new D[3]};} // 调用 ~D 3 次
}

C++智能指针中unique_ptr部分内容的讲解相关推荐

  1. 深入学习c++--智能指针(三) unique_ptr

    1. 几种智能指针 1. auto_ptr: c++11中推荐不使用他(放弃) 2. shared_ptr: 拥有共享对象所有权语义的智能指针 3. unique_ptr: 拥有独有对象所有权语义的智 ...

  2. C++11智能指针(unique_ptr、shared_ptr、weak_ptr)boost::scoped_ptr

    C++11智能指针(unique_ptr.shared_ptr.weak_ptr)_-码农小非-的专栏-CSDN博客_c++ shared_ptr weak_ptr 原创)智能指针拾遗 (原创)智能指 ...

  3. C++11新特性——智能指针之unique_ptr

    此课件及源代码来自B站up主:码农论坛,该文章仅作为本人学习笔记使用. unique_ptr独享它指向的对象,也就是说,同时只有一个unique_ptr指向同一个对象,当这个unique_ptr被销毁 ...

  4. 智能指针之unique_ptr

    unique_ptr实现的是专属所有权语义,用于独占它所指向的资源对象的场合.某个时刻只能有一个unique_ptr指向一个动态分配的资源对象,也就是这个资源不会被多个unique_ptr对象同时占有 ...

  5. C++自学24:唯一智能指针(make_unique/unique_ptr/reset/release/get/13.1)

    使用make_unique获取一个智能指针,智能指针的类型是unique_ptr // a不是数组,小括号里的就是值 std::unique_ptr<int> a = std::make_ ...

  6. 32. 对c++中的smart pointer四个智能指针shared_ptr,unique_ptr,weak_ptr,auto_ptr的理解

    C++里面的四个智能指针: auto_ptr, shared_ptr, weak_ptr, unique_ptr 其中后三个是c++11支持,并且第一个已经被11弃用. 智能指针的作用是管理一个指针, ...

  7. C++智能指针:unique_ptr详解

    文章目录 unique_ptr描述 声明 作用 函数指针描述 总结 unique_ptr描述 声明 头文件:<memory> 模版类: 默认类型template <class T, ...

  8. 智能指针(三):unique_ptr使用简介

    文章转自:http://blog.csdn.net/weiwenhp/article/details/8708281 版权归原作者! 我们知道auto_ptr通过复制构造或者通过=赋值后,原来的aut ...

  9. C++ -- 智能指针 auto_ptr,unique_ptr,shared_ptr的简单实现和原理

    一,为什么需要智能指针 智能指针是一种预防型的内存泄漏的解决方案.由于C++没有垃圾回收器机制,所以每次new出来的资源都需要手动的delete,如果没有手动释放,就会造成资源泄漏等问题.因此,为了避 ...

最新文章

  1. DELL服务器重做RAID
  2. Citrix_XenServer-6.1安装过程详解(转)
  3. Matlab生成棋盘格点图
  4. java long bigdecimal,通过Java中的long创建BigDecimal值
  5. Kudu报错:你的主机中的软件终止了一个已建立的链接
  6. 免校准的电量计量芯片_单相电能表如何校准(单相电能计量芯片+MCU)
  7. JAVA面试要点002_Git中fetch和pull的区别
  8. 想做好seo优化,关键词的选择可是重中之重!
  9. NSObject的hash方法
  10. 行政界线类型代码_行政区划代码的代码表
  11. 各种ActiveX控件下载地址分享
  12. MATLAB学习笔记————(MATLAB的矩阵及其操作②)
  13. matlab设置柱状图空白,MATLAB画柱状图时形状填充及颜色改变问题
  14. 建筑智能化资质办理条件
  15. 考研高等数学张宇30讲笔记——第二讲 数列极限
  16. PHP将一个pdf 拆分按需要页码组装新的pdf
  17. 如何批量打印 带图片名字的图片?Word 宏命令
  18. 找了许久,终于找到一篇关于GStreamer架构的说的比较详细和底层的文章
  19. (38)STM32——NRF24L01无线通信
  20. 如何实现ABC三个线程按顺序执行十次

热门文章

  1. python入侵数据库数据库_一个简单的Python访问Mysql数据库例子
  2. 微软认证及课程简写含义
  3. 【转】C# 彻底搞懂async/await
  4. ASP.Net请求处理机制初步探索之旅 - Part 1 前奏
  5. 第一节: Timer的定时任务的复习、Quartz.Net的入门使用、Aop思想的体现
  6. 哈希桶 entry_哈希表代码实现
  7. python可以开发驱动吗_Python机器学习实践:测试驱动的开发方法
  8. 【JS 逆向百例】百度翻译接口参数逆向
  9. 【Python CheckiO 题解】I Love Python!
  10. 【牛客 - 21302】被3整除的子序列(线性dp)