目录

1 auto_ptr与unique_ptr

2 unique_ptr特性

3 unique_ptr可以:

4 unique_ptr对auto_ptr的改进如下:

4.1 auto_ptr支持拷贝构造与赋值操作,但unique_ptr不直接支持

4.2 unique_ptr 可为动态申请的资源提供异常安全保证

4.3 unique_ptr可以用在函数返回值中,返回动态申请资源的所有权

4.4 unique_ptr可做为容器元素,在容器中保存指针

4.5 unique_ptr可管理动态数组

5 示例



1 auto_ptr与unique_ptr

auto_ptr是用于C++11之前的智能指针。由于 auto_ptr 基于排他所有权模式:两个指针不能指向同一个资源,复制或赋值都会改变资源的所有权。auto_ptr 主要有两大问题:

  • o 复制和赋值会改变资源的所有权,不符合人的直觉。
  • o 在 STL 容器中无法使用auto_ptr ,因为容器内的元素必需支持可复制(copy constructable)和可赋值(assignable)。

2 unique_ptr特性

  • o 拥有它所指向的对象
  • o 无法进行复制构造,也无法进行复制赋值操作
  • o 保存指向某个对象的指针,当它本身离开作用域时会自动释放它指向的对象。

3 unique_ptr可以:

  • o 为动态申请的内存提供异常安全
  • o 将动态申请内存的所有权传递给某个函数
  • o 从某个函数返回动态申请内存的所有权
  • o 在容器中保存指针

unique_ptr十分依赖于右值引用和移动语义。

在C++11中已经放弃auto_ptr转而推荐使用unique_ptr和shared_ptr。unique跟auto_ptr类似同样只能有一个智能指针对象指向某块内存.但它还有些其他特性。

4 unique_ptr对auto_ptr的改进如下:

4.1 auto_ptr支持拷贝构造与赋值操作,但unique_ptr不直接支持

auto_ptr通过拷贝构造或者operator=赋值后,对象所有权转移到新的auto_ptr中去了,原来的auto_ptr对象就不再有效,这点不符合人的直觉。unique_ptr则直接禁止了拷贝构造与赋值操作。

auto_ptr<int> ap(new int(10));
auto_ptr<int> one (ap) ; // ok
auto_ptr<int> two = one; //okunique_ptr<int> ap(new int(10));
unique_ptr<int> one (ap) ; // 会出错
unique_ptr<int> two = one; //会出错

4.2 unique_ptr 可为动态申请的资源提供异常安全保证

我们先来看看下面这一段代码:

void Func()
{int *p = new int(5);// ...(可能会抛出异常)delete p;
}

这是我们传统的写法:当我们动态申请内存后,有可能我们接下来的代码由于抛出异常或者提前退出(if语句)而没有执行delete操作。

解决的方法是使用unique_ptr来管理动态内存,只要unique_ptr指针创建成功,其析构函数都会被调用。确保动态资源被释放。

void Func()
{unique_ptr<int> p(new int(5));// ...(可能会抛出异常)
}

4.3 unique_ptr可以用在函数返回值中,返回动态申请资源的所有权

unique_ptr像上面这样一般意义上的复制构造和赋值或出错,但在函数中作为返回值却可以用.

unique_ptr<int> Func(int p)
{unique_ptr<int> pInt(new int(p));return pInt; // 返回unique_ptr
}int main() {int p = 5;unique_ptr<int> ret = Func(p);cout << *ret << endl;// 函数结束后,自动释放资源
}

4.4 unique_ptr可做为容器元素,在容器中保存指针

我们知道auto_ptr不可做为容器元素,会导致编译错误。虽然unique_ptr同样不能直接做为容器元素,但可以通过move语意实现。

unique_ptr<int> sp(new int(88) );
vector<unique_ptr<int> > vec;
vec.push_back(std::move(sp));
// vec.push_back( sp ); error:
// cout << *sp << endl;

std::move让调用者明确知道拷贝构造、赋值后会导致之前的unique_ptr失效。

4.5 unique_ptr可管理动态数组

标准库提供了一个可以管理动态数组的unique_ptr版本。

int main() {unique_ptr<int[]> p(new int[5] {1, 2, 3, 4, 5});p[0] = 0; // 重载了operator[]
}

5 示例


#include <memory>
#include <vector>
#include <cassert>
using namespace std;unique_ptr<int> GetVal( )
{unique_ptr<int> up(new int(10));return up;
}int main()
{// auto_ptr支持拷贝构造与赋值,拷贝构造或赋值后对象所有权转移auto_ptr<int> aPtr(new int(10));auto_ptr<int> a1 (aPtr);  // call copy constuctor, OKassert(aPtr.get() == nullptr && a1.get() != nullptr);auto_ptr<int> a2(NULL);a2 = a1;        // call operator=, OKassert(a1.get() == nullptr && a2.get() != nullptr);// unique_ptr不支持直接拷贝构造与赋值unique_ptr<int> uPtr(new int(10));// unique_ptr<int> u1 (uPtr);       // call copy constructor, error // Error: Call to implicitly-deleted copy constructor of 'unique_ptr<int>'// unique_ptr<int> u2 = nullptr;// u2 = uPtr;               // call operator=, error// Error: Overload resolution selected implicitly-deleted copy assignment operator// unique_ptr支持move语意的拷贝构造unique_ptr<int> u1(std::move(uPtr));assert(uPtr == nullptr && u1 != nullptr);// unique_ptr支持move语意的赋值unique_ptr<int> u2 = std::move(u1) ; // 把u1所指的内存转给u2了,而u1不再拥有该内存assert(u1 == nullptr && u2 != nullptr);// unique_ptr通过move语意可放入STL容器unique_ptr<int> sp(new int(100));vector<unique_ptr<int>> vec;vec.push_back(std::move(sp));// vec.push_back(sp);// Error: Call to implicitly-deleted copy constructor of 'std::__1::unique_ptr<int, std::__1::default_delete<int> >'assert(sp == nullptr);// cout << *sp << endl;  // crash at this point, sp is nullptr nowunique_ptr<int> g_uPtr = GetVal();   //ok
}

C++_auto_ptr与unique_ptr智能指针相关推荐

  1. C++新特性探究(18.2):C++11 unique_ptr智能指针详解

    C++11 unique_ptr智能指针   作为智能指针的一种,unique_ptr 指针自然也具备"在适当时机自动释放堆内存空间"的能力.和shared_ptr指针最大的不同之 ...

  2. unique_ptr智能指针

    基本概念: unique_ptr是专属所有权,所以unique_ptr管理的内存,智能被一个对象持有,不支持赋值和复制. 移动语意: unique_ptr禁止了拷贝语意,但有时我们也需要转移所有权,于 ...

  3. C++11 unique_ptr智能指针详解

    文章目录 0.应用场景 1.初始化方式 2.常用操作 3.例子 例子1 创建unique_ptr并以引用形式传递给函数 例子2 用vector管理unique_ptr 例子3 unique_ptr作为 ...

  4. C++ 智能指针(unique_ptr / shared_ptr)代码实现

    文章目录 unique_ptr 智能指针的实现 shared_ptr 智能指针的实现 指针类型转换 unique_ptr 智能指针的实现 一个对象只能被单个unique_ptr 所拥有. #inclu ...

  5. C++11中的智能指针unique_ptr、shared_ptr和weak_ptr详解

    目录 1.引言 2.什么是智能指针? 3.在Visual Studio中查看智能指针的源码实现 4.独占式指针unique_ptr 4.1.查看unique_ptr的源码实现片段 4.2.为什么uni ...

  6. 【C++ 语言】智能指针 引入 ( 内存泄漏 | 智能指针简介 | 简单示例 )

    文章目录 I . 智能指针 引入 II . 智能指针 简介 III . 智能指针 简单示例 I . 智能指针 引入 1 . 示例前提 : 定义一个 Student 类 , 之后将该类对象作为智能指针指 ...

  7. 【C++】智能指针 Smart Pointer

    智能指针 智能指针 Smart Pointer auto_ptr 智能指针的自实现 shared_ptr weak_ptr unique_ptr 智能指针 Smart Pointer 用来改善传统指针 ...

  8. c++11:智能指针

    我们在程序运行的过程中,经常出现段错误.内存持续增大等,是C++显式内存管理存在的问题,主要归纳为以下几点: 野指针:一些内存单元已经释放,但之前指向它的指针还在使用. 重复释放:程序试图释放已经被释 ...

  9. cwinthread*线程指针怎么销毁结束_C++知识点:智能指针

    之前面试虾皮时问到了智能指针相关知识点,当时答的很没有条理,这里整理一下权当笔记. 根据<C++ Primer Plus>中的解释,智能指针是行为类似于指针的模板对象.当函数分配堆内存时, ...

  10. C++ 手动实现简单的智能指针类

    何为智能指针,即不需要用户再自动手动New和Delete掉,由内部类进行new和delete,这样可以防止用户忘记释放掉指针而造成的内存泄漏. 这里简单的实现unique_ptr智能指针的方式. 头文 ...

最新文章

  1. vscode 开发lua搭建
  2. 用Greasemonkey脚本收藏网站会员信息到本地
  3. idea控制台输出乱码
  4. 用 Python 和 OpenCV 检测和跟踪运动对象
  5. flex 鼠标放在组件上变手型
  6. Android开发之微信支付获取签名小工具分享
  7. 四川大学2015年数学分析考研试题
  8. 【elasticsearch】FileAlreadyExistsException:/home/elasticsearch-6.8.0/config/elasticsearch.keysto
  9. 整合Solr到Tomcat服务器,并配置IK分词
  10. SpringBoot学习---yaml配置
  11. FDB表-ARP表-路由表
  12. linux的百度网盘客户端
  13. 智能推荐系统开发中的十个关键注意点
  14. 90后生态 | 我不敢看体检报告了!!!
  15. 墙外干货:如何通过风格指南驱动模块化交互设计
  16. 2k分辨率显示器 浏览器_如何使浏览器使用显示器的完整分辨率?
  17. SpringBoot项目中配置文件敏感信息(数据用户名、密码)的加密
  18. 给定平面上任意三个点的坐标(x1​,y1​)、(x2​,y2​)、(x3​,y3​),检验它们能否构成三角形。
  19. Redis高可用集群-哨兵模式(Redis-Sentinel)搭建配置教程【Windows环境】
  20. dirname $0

热门文章

  1. 在QTP中巧用WebTable对象的ChildItem方法进行测试
  2. 大数据技术Hadoop介绍
  3. Spring 与 SpringMVC 容器父子关系引出的相应问题
  4. foxmail创建163公司企业邮箱的时候会出现ERR Unable to log on
  5. (原创)EDK中常用文件
  6. Java实现Oracle数据库导入
  7. vue中this.$set的用法
  8. C#开发之DataGridView填充数据使用小结
  9. Thinking in Java 9.9 接口与工厂
  10. gdal-3.1.2-release下载页面出错