C++11 unique_ptr智能指针详解
作为智能指针的一种,unique_ptr 指针自然也具备“在适当时机自动释放堆内存空间”的能力。和 shared_ptr
指针最大的不同之处在于,unique_ptr 指针指向的堆内存无法同其它 unique_ptr 共享,也就是说,每个 unique_ptr
指针都独自拥有对其所指堆内存空间的所有权。
这也就意味着,每个 unique_ptr 指针指向的堆内存空间的引用计数,都只能为 1,一旦该 unique_ptr 指针放弃对所指堆内存空间的所有权,则该空间会被立即释放回收。
unique_ptr 智能指针是以模板类的形式提供的,unique_ptr<T>(T 为指针所指数据的类型)定义在<memory>头文件,并位于 std 命名空间中。因此,要想使用 unique_ptr 类型指针,程序中应首先包含如下 2 条语句:
- #include <memory>
- using namespace std;
第 2 句并不是必须的,可以不添加,则后续在使用 unique_ptr 指针时,必须标注
std::。
unique_ptr智能指针的创建
考虑到不同实际场景的需要,unique_ptr<T> 模板类提供了多个实用的构造函数,这里给读者列举了几种常用的构造 unique_ptr 智能指针的方式。
1) 通过以下 2 种方式,可以创建出空的 unique_ptr 指针:
- std::unique_ptr<int> p1();
- std::unique_ptr<int> p2(nullptr);
2) 创建 unique_ptr 指针的同时,也可以明确其指向。例如:
- std::unique_ptr<int> p3(new int);
由此就创建出了一个 p3 智能指针,其指向的是可容纳 1 个整数的堆存储空间。
和可以用 make_shared<T>() 模板函数初始化 shared_ptr 指针不同,C++11 标准中并没有为 unique_ptr 类型指针添加类似的模板函数。
3) 基于 unique_ptr 类型指针不共享各自拥有的堆内存,因此 C++11 标准中的 unique_ptr 模板类没有提供拷贝构造函数,只提供了移动构造函数。例如:
- std::unique_ptr<int> p4(new int);
- std::unique_ptr<int> p5(p4);//错误,堆内存不共享
- std::unique_ptr<int> p5(std::move(p4));//正确,调用移动构造函数
值得一提的是,对于调用移动构造函数的 p4 和 p5 来说,p5 将获取 p4 所指堆空间的所有权,而 p4 将变成空指针(nullptr)。
4) 默认情况下,unique_ptr 指针采用 std::default_delete<T>
方法释放堆内存。当然,我们也可以自定义符合实际场景的释放规则。值得一提的是,和 shared_ptr 指针不同,为 unique_ptr
自定义释放规则,只能采用函数对象的方式。例如:
- //自定义的释放规则
- struct myDel
- {
- void operator()(int *p) {
- delete p;
- }
- };
- std::unique_ptr<int, myDel> p6(new int);
- //std::unique_ptr<int, myDel> p6(new int, myDel());
unique_ptr<T>模板类提供的成员方法
为了方便用户使用 unique_ptr 智能指针,unique_ptr<T> 模板类还提供有一些实用的成员方法,它们各自的功能如表 1 所示。
| 成员函数名 | 功 能 |
|---|---|
| operator*() | 获取当前 unique_ptr 指针指向的数据。 |
| operator->() | 重载 -> 号,当智能指针指向的数据类型为自定义的结构体时,通过 -> 运算符可以获取其内部的指定成员。 |
| operator =() | 重载了 = 赋值号,从而可以将 nullptr 或者一个右值 unique_ptr 指针直接赋值给当前同类型的 unique_ptr 指针。 |
| operator []() | 重载了 [] 运算符,当 unique_ptr 指针指向一个数组时,可以直接通过 [] 获取指定下标位置处的数据。 |
| get() | 获取当前 unique_ptr 指针内部包含的普通指针。 |
| get_deleter() | 获取当前 unique_ptr 指针释放堆内存空间所用的规则。 |
| operator bool() | unique_ptr 指针可直接作为 if 语句的判断条件,以判断该指针是否为空,如果为空,则为 false;反之为 true。 |
| release() | 释放当前 unique_ptr 指针对所指堆内存的所有权,但该存储空间并不会被销毁。 |
| reset(p) | 其中 p 表示一个普通指针,如果 p 为 nullptr,则当前 unique_ptr 也变成空指针;反之,则该函数会释放当前 unique_ptr 指针指向的堆内存(如果有),然后获取 p 所指堆内存的所有权(p 为 nullptr)。 |
| swap(x) | 交换当前 unique_ptr 指针和同类型的 x 指针。 |
除此之外,C++11标准还支持同类型的 unique_ptr 指针之间,以及 unique_ptr 和 nullptr 之间,做 ==,!=,<,<=,>,>= 运算。
下面程序给大家演示了 unique_ptr 智能指针的基本用法,以及该模板类提供了一些成员方法的用法:
- #include <iostream>
- #include <memory>
- using namespace std;
- int main()
- {
- std::unique_ptr<int> p5(new int);
- *p5 = 10;
- // p 接收 p5 释放的堆内存
- int * p = p5.release();
- cout << *p << endl;
- //判断 p5 是否为空指针
- if (p5) {
- cout << "p5 is not nullptr" << endl;
- }
- else {
- cout << "p5 is nullptr" << endl;
- }
- std::unique_ptr<int> p6;
- //p6 获取 p 的所有权
- p6.reset(p);
- cout << *p6 << endl;;
- return 0;
- }
程序执行结果为:
10
p5 is nullptr
10
------------------------------ 上面有误-------------
std::unique_ptr::release
pointer release() noexcept;
Releases ownership of its stored pointer, by returning its value and replacing it with a null pointer.
This call does not destroy the managed object, but the unique_ptr
object is released from the responsibility of deleting the object. Some
other entity must take responsibility for deleting the object at some
point.
To force the destruction of the object pointed, either use member function reset or perform an assignment operation on it.
Parameters
none
Return value
A pointer to the object managed by unique_ptr before the call.
pointer is a member type, defined as the pointer type that points to the type of object managed.
Example
|
|
Output:
manual_pointer points to 10 |
See also
- unique_ptr::reset
- Reset pointer (public member function
)
- unique_ptr::get
- Get pointer (public member function
)
- unique_ptr::operator=
- unique_ptr assignment (public member function
)
C++11 unique_ptr智能指针详解的更多相关文章
- [转]C++ 智能指针详解
转自:http://blog.csdn.net/xt_xiaotian/article/details/5714477 C++ 智能指针详解 一.简介 由于 C++ 语言没有自动内存回收机制,程序员每 ...
- C++ 智能指针详解(转)
C++ 智能指针详解 一.简介 由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete.程序员忘记 delete,流程太复杂,最终导致没有 delete,异常 ...
- 【C++】智能指针详解(一):智能指针的引入
智能指针是C++中一种利用RAII机制(后面解释),通过对象来管理指针的一种方式. 在C++中,动态开辟的内存需要我们自己去维护,在出函数作用域或程序异常退出之前,我们必须手动释放掉它,否则的话就会引 ...
- [C++11新特性] 智能指针详解
动态内存的使用很容易出问题,因为确保在正确的时间释放内存是极为困难的.有时我们会忘记释放内存产生内存泄漏,有时提前释放了内存,再使用指针去引用内存就会报错. 为了更容易(同时也更安全)地使用动态内存, ...
- 【C++】智能指针详解
转自:https://blog.csdn.net/flowing_wind/article/details/81301001 参考资料:<C++ Primer中文版 第五版>我们知道除了静 ...
- C++智能指针详解
本文出自http://mxdxm.iteye.com/ 一.简介 由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete.程序员忘记 delete,流程太复杂,最 ...
- 【转】C++ 智能指针详解
一.简介 由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete.程序员忘记 delete,流程太复杂,最终导致没有 delete,异常导致程序过早退出,没有执行 ...
- 【C++】智能指针详解(二):auto_ptr
首先,我要声明auto_ptr是一个坑!auto_ptr是一个坑!auto_ptr是一个坑!重要的事情说三遍!!! 通过上文,我们知道智能指针通过对象去管理指针,在构造对象时完成资源的分配及初始化,在 ...
- c++11之智能指针
在c++98中,智能指针通过一个模板“auto_ptr”来实现,auto_ptr以对象的方式来管理堆分配的内存,在适当的时间(比如析构),释放所获得的内存.这种内存管理的方式只需要程序员将new操作返 ...
随机推荐
- Linux磁盘配额与LVM
一.LVM概述 逻辑卷管理 Logical Volume Manager二.LVM机制的基本概念三.LVM的管理命令 ① 主要命令 ② ==LVM逻辑卷操作流程== ③ 举例四.磁盘配额概述 ...
- c语言:DEV-C++5.10调试设置
DEV-C++调试设置方法:默认不能调试,打开调试的方法: 1.点击"工具"菜单--编译选项--"代码生成/优化"--连接器--"产生调试信息&quo ...
- Red Hat系统下安装gcc
这篇是在客户服务器上安装redis碰到的问题.服务器是RedHat,无法直接安装gcc,导致Redis无法安装的解决办法: 1.make redis时候报下面这样的错,原因就是gcc没有安装. ...
- [003] - JavaSE面试题(三):JavaSE语法(1)
第一期:Java面试 - 100题,梳理各大网站优秀面试题.大家可以跟着我一起来刷刷Java理论知识 [003] - JavaSE面试题(三):JavaSE语法(1) 第1问:& 和 & ...
- 【Linux命令】在当前目录下查找出现特定字符串的文件位置信息
有时候我们我会碰到这样的问题:我要查找一个字符串在多个文件里总共出现了几次,或者一个方法.一个函数在项目里调用了几次,都在哪里调用,那我们要如何查找,如何统计这些信息呢? 场景复现 首先,要查找字符串 ...
- Odoo的附件大小限制
Odoo使用binary类型来保存附件数据,可以直接支持附件数据的上传.但是在实际使用中,有可能遇到附件文件大小超过限制的情况,如下图: 但是ERP定制过程中难免会遇到客户确实需要上传超大附件,那么怎 ...
- C++ 定义默认值void locals_index(int reg, int offset = 1);
看jvm源码的时候怎么也看不懂,来回看了几次了就是关于iload 6 指令的解析 def(Bytecodes::_lload , ubcp|____|____|____, vtos, ltos, ll ...
- 记录一个SQL语句 case select 1
select Code, CodeName, CodeAlias, ComCode, OtherSign from ldcode where codetype = 'edorapptype' and ...
- java封装基础详解
java封装基础详解 java的封装性即是信息隐藏,把对象的属性和行为结合成一个相同的独立单体,并尽可能地隐藏对象的内部细节. 封装的特性是对属性来讲的. 封装的目标就是要实现软件部件的"高 ...
- 某学院m3u8视频解密获取分析实战分享
[免责声明]本文来源于作者个人学习整理,仅供学习交流使用,不构成商业目的.所有资源均系本人个人学习或网络收集,仅提供一个展示.介绍.观摩学习的博文,不对其内容的准确性.可靠性.正当性.安全性.合法性等 ...