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操作返 ...
随机推荐
- selenium异步爬取(selenium+Chromedriver)
在我们进行数据爬去的过程中,我们有时候会遇到异步加载信息的情况,以豆瓣电影分来排行榜为例,当我们在查看数据的过程中,会发现网页源码中并不包含我们想要的全部数据,但是当我们在进行向下滚动的时候,数据会一 ...
- 前端开发入门到进阶第三集【JavaScript中如何将html字符串转化为Jquery对象或者Dom对象】
https://www.cnblogs.com/mingjiatang/p/4746845.html
- python之数据驱动ddt操作(方法三)
import unittestfrom selenium import webdriverfrom selenium.webdriver.common.by import Byimport unitt ...
- UBUNTU 16.04 LTS SERVER 手动升级 MariaDB 到最新版 10.2
UBUNTU 16.04 LTS SERVER 手动升级 MariaDB 到最新版 10.2 1. 起因 最近因为不同软件的数据问题本来只是一些小事弄着弄着就越弄越麻烦了,期间有这么个需求,没看到有中 ...
- C#.NET RSA 私钥签名 公钥验证签名
C#.NET RSA 私钥签名 公钥验证签名 公钥验签 1.待签名字符串转为byte数组时,一般使用UTF8. 2.将私钥字符串(PKCS8或PKCS1格式)转为C#.NET的RSACryptoSer ...
- P4774-屠龙勇士-扩展中国剩余定理
屠龙勇士 很久很久以前,巨龙突然出现,带来了灾难带走公主又消失不见.王国十分危险,世间谁最勇敢,一位英雄出现-- 学习于该大佬博客 那么你就是这位英雄,不过不同的是,你面对的是一群巨龙,虽然巨龙都不会 ...
- 《Node+MongoDB+React 项目实战开发》已出版
前言 从深圳回长沙已经快4个月了,除了把车开熟练了外,并没有什么值得一提的,长沙这边要么就是连续下一个月雨,要么就是连续一个月高温暴晒,上班更是没啥子意思,长沙这边的公司和深圳落差挺大的,薪资也是断崖 ...
- 基于Gin+Gorm框架搭建MVC模式的Go语言后端系统
文/朱季谦 环境准备:安装Gin与Gorm 本文搭建准备环境:Gin+Gorm+MySql. Gin是Go语言的一套WEB框架,在学习一种陌生语言的陌生框架,最好的方式,就是用我们熟悉的思维去学.作为 ...
- Odoo的附件大小限制
Odoo使用binary类型来保存附件数据,可以直接支持附件数据的上传.但是在实际使用中,有可能遇到附件文件大小超过限制的情况,如下图: 但是ERP定制过程中难免会遇到客户确实需要上传超大附件,那么怎 ...
- 使用turtle库画一朵玫瑰花带文字
参考链接:https://jingyan.baidu.com/article/d169e18689f309026611d8c8.html https://blog.csdn.net/weixin_41 ...