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操作返 ...
随机推荐
- 『动善时』JMeter基础 — 55、使用非GUI模式运行JMeter(命令行模式)
目录 1.JMeter的非GUI模式说明 2.为什么使用非GUI模式运行JMeter 3.使用非GUI模式运行JMeter (1)非GUI模式运行JMeter步骤 (2)其它参数说明 4.CLI模式运 ...
- ESCMScript6(3)Promise对象
1. Promise的含义 Promise 是异步编程的一种解决方案,比传统的解决方案--回调函数和事件--更合理和更强大.它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了P ...
- Python+Requests+异步线程池爬取视频到本地
1.本次项目为获取梨视频中的视频,再使用异步线程池下载视频到本地 2.获取视频时,其地址中的Url是会动态变化,不播放时src值为图片的地址,播放时src值为mp4格式 3.查看视频链接是否存在aja ...
- springboot-8-企业开发
一.邮件发送 流程: mbqplwpheeyvgdjh 首先需要开启POS3/SMTP服务,这是一个邮件传输协议 点击开启 导入依赖 <!--mail--> <dependency& ...
- PAT乙级:1069 微博转发抽奖 (20分)
PAT乙级:1069 微博转发抽奖 (20分) 题干 小明 PAT 考了满分,高兴之余决定发起微博转发抽奖活动,从转发的网友中按顺序每隔 N 个人就发出一个红包.请你编写程序帮助他确定中奖名单. 输入 ...
- swagger是什么(十六)
前言: swagger:神气十足,大摇大摆 在用Springboot进行开发时,有的实体类上用到了注解@ApiModelProperty("接受人代码"),特此整理此注解的出处及作 ...
- 学会这十招,轻松搜索github优质项目
大家好,我是青空. 今天我想给大家分享一下使用 GitHub 的一些心得体会.之前我是在分享 GitHub上的一些开源项目,通过这段时间的收集工作,我积累了一些相关的经验在这里分享给大家. 我做了一个 ...
- 文件包含 & LFI-labs靶场
文件包含漏洞学习 冲冲冲,好好学习 2020.1.30 认真对待自己做出的每一个决定 知识与实践 Q:什么是文件包含? A:简单一句话,为了更好地使用代码的重用性,引入了文件包含函数,可以通过文件包含 ...
- Optional解决空指针
Java 8 Optional 类 Java 8 新特性 Optional 类是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象. O ...
- Python语法之用户交互与基本运算符
一.与用户交互 1.接收用户输入 python3中的input会把用户输入的所有内容都存成str类型 age = input("请输入您的年龄: ") # "内容&quo ...