原创作品,转载请标明:http://blog.csdn.net/Xiejingfa/article/details/50759210

在前面一篇文章中,我们了解了C++11中引入的智能指针之一shared_ptr,今天,我们来介绍一下另一种智能指针unique_ptr。


unique_ptr介绍

unique是独特的、唯一的意思,故名思议,unique_ptr可以“独占”地拥有它所指向的对象,它提供一种严格意义上的所有权。这一点和我们前面介绍的shared_ptr类型指针有很大的不同:shared_ptr允许多个指针指向同一对象,而unique_ptr在某一时刻只能有一个指针指向该对象。unique_ptr保存指向某个对象的指针,当它本身被删除或者离开其作用域时会自动释放其指向对象所占用的资源。

下面,我们就来具体介绍一下unique_ptr的基本特性。

1、如何创建unique_ptr

unique_ptr不像shared_ptr一样拥有标准库函数make_shared来创建一个shared_ptr实例。要想创建一个unique_ptr,我们需要将一个new 操作符返回的指针传递给unique_ptr的构造函数。

示例:

int main() {// 创建一个unique_ptr实例unique_ptr<int> pInt(new int(5));cout << *pInt;
}
  • 1
  • 2
  • 3
  • 4
  • 5

2、无法进行复制构造和赋值操作

unique_ptr没有copy构造函数,不支持普通的拷贝和赋值操作。

int main() {// 创建一个unique_ptr实例unique_ptr<int> pInt(new int(5));unique_ptr<int> pInt2(pInt);    // 报错unique_ptr<int> pInt3 = pInt;   // 报错
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3、可以进行移动构造和移动赋值操作

unique_ptr虽然没有支持普通的拷贝和赋值操作,但却提供了一种移动机制来将指针的所有权从一个unique_ptr转移给另一个unique_ptr。如果需要转移所有权,可以使用std::move()函数。

示例:

int main() {unique_ptr<int> pInt(new int(5));unique_ptr<int> pInt2 = std::move(pInt);    // 转移所有权//cout << *pInt << endl; // 出错,pInt为空cout << *pInt2 << endl;unique_ptr<int> pInt3(std::move(pInt2));
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

4、可以返回unique_ptr

unique_ptr不支持拷贝操作,但却有一个例外:可以从函数中返回一个unique_ptr。

示例:

unique_ptr<int> clone(int p)
{unique_ptr<int> pInt(new int(p));return pInt;    // 返回unique_ptr
}int main() {int p = 5;unique_ptr<int> ret = clone(p);cout << *ret << endl;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

unique_ptr使用场景

1、为动态申请的资源提供异常安全保证

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

void Func()
{int *p = new int(5);// ...(可能会抛出异常)delete p;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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

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

void Func()
{unique_ptr<int> p(new int(5));// ...(可能会抛出异常)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2、返回函数内动态申请资源的所有权

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;// 函数结束后,自动释放资源
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

3、在容器中保存指针

int main() {vector<unique_ptr<int>> vec;unique_ptr<int> p(new int(5));vec.push_back(std::move(p));    // 使用移动语义
}
  • 1
  • 2
  • 3
  • 4
  • 5

4、管理动态数组

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

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

5、作为auto_ptr的替代品

【C++11新特性】 C++11智能指针之unique_ptr相关推荐

  1. c++11新特性_c++11新特性(四)

    4.lambda.bind.function 4.1.直接lambda表达式 lamda表达式不仅仅是一个语法新特性,对于没有用过java或C#lamda表达式读者,C++11的lamda表达式在一定 ...

  2. Java 11新特性_java 11 值得关注的新特性

    JEP 181: Nest-Based Access Control 基于嵌套的访问控制 JEP 309: Dynamic Class-File Constants 动态类文件 JEP 315: Im ...

  3. COSMIC的后端学习之路——2.1 C++11新特性(1)

    2.1 C++11新特性(1) 知识树 1.智能指针 (1)std::shared_ptr:共享的智能指针 ①初始化 ②获取原始指针 ③指定删除器(自定义删除对象) ④一些错误用法 (2)std::u ...

  4. 【C++11新特性】 C++11智能指针之weak_ptr

    http://blog.csdn.net/xiejingfa/article/details/50772571 原创作品,转载请标明:http://blog.csdn.net/Xiejingfa/ar ...

  5. c++11新特性_【C++11新特性】 C++11智能指针之weak_ptr

    如题,我们今天要讲的是 C++11 引入的三种智能指针中的:weak_ptr. 在学习 weak_ptr 之前最好对 shared_ptr 有所了解.如果你还不知道 shared_ptr 是何物,可以 ...

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

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

  7. this指针_c++11新特性之智能指针

    很多人谈到c++,说它特别难,可能有一部分就是因为c++的内存管理吧,不像java那样有虚拟机动态的管理内存,在程序运行过程中可能就会出现内存泄漏,然而这种问题其实都可以通过c++11引入的智能指针来 ...

  8. 深入浅出之C++11新特性

    1. auto类型赋予新含义 1.1 auto类型定义 在之前的 C++ 版本中,auto 关键字用来指明变量的存储类型,它和 static 关键字是相对的.auto 表示变量是自动存储的,这也是编译 ...

  9. C++11新特性的总结

    C++11新特性 auto关键字(C++11)基于范围的for循环(C++11). 指针空值nullptr(C++11) C++动态内存管理 序列式容器 array forward_list; 继承和 ...

  10. C++11新特性以及std::thread多线程编程

    一 .C++11新特性 1. auto 类型推导 1.1 当=号右边的表达式是一个引用类型时,auto会把引用抛弃,直接推导出原始类型: 1.2 当=号右边的表达式带有const属性时,auto不会使 ...

最新文章

  1. 【FFmpeg】便捷函数汇总(持续更新中...)
  2. Self Ogannizing Maps(SOM)自组织映射
  3. Android中在使用Room时提示:Cannot figure out how to save this field into database. You can consider adding a
  4. 用interrupt()中断Java线程
  5. ocp oracle 考试报名_获得Oracle认证对拓展职业前景的影响
  6. Apache 配置文件:.htaccess
  7. 用粉红噪声煲机_虾米歌单 | 【科学煲耳机】(白噪音 粉红噪音 无损) - 虾米音乐...
  8. 测度论与概率论基础(程士宏)学习笔记(二)
  9. USB数据采集卡,Labjack U6、T7 采集卡 VB、C++ 编程范例
  10. 团队开发如何评估工作量
  11. zotero+坚果云
  12. 自然语言处理训练营NLP--笔记
  13. 让Kodu动起来---Kodu少儿编程第五天
  14. 计算机数值分析-插值法-差商-04
  15. rk3288_updata
  16. 《肖申克的救赎》到底救赎了什么?谁在救赎?
  17. java 拒绝连接_java.net.ConnectException:连接被拒绝
  18. HTML基础 + 实例解析
  19. 【PHP框架 | Laravel8 系列5】 - 视图与CSRF保护
  20. 服务器被入侵当做挖矿肉鸡

热门文章

  1. 5月学习总结(Ant-Design,mustache,require.js,grunt)
  2. 监听微信、支付宝等移动app及浏览器的返回、后退、上一页按钮的事件方法
  3. CentOS 7安装redis及php扩展
  4. Android转载一:Android文件命名规范
  5. 二进制逆向工程师_利用Ghidra逆向分析Go二进制程序(下篇)
  6. mysql5.7运行按钮_MySQL 5.7.* 启动问题
  7. php 秒杀并发怎么做,PHP实现高并发下的秒杀功能–Laravel
  8. @select 怎么写存储过程_MySQL4:存储过程和函数
  9. html鼠标事件没反应,鼠标有时候点击没反应怎么解决
  10. Ubuntu下安装OpenSSH Server并在客户端远程连接Ubuntu