探究C++11智能指针之std::unique_ptr

背景

谈起C++,它被公认为最难学的编程语言之一,不仅语法知识点广泛,细节内容之多,学习难度和学习周期也长,导致好多新入行的开发者对C++“敬而远之”,甚至“从入门到放弃”。自C++11开始,好多C++程序员慢慢的感受到了C++的魅力所在,似乎难度也越来越小。

 

本文要讲的是C++11引入的智能指针之std::unique_ptr。​

std::unique_ptr系C++11引入的智能指针,拥有资源的唯一所有权,头文件 #include <memory>。

unique_ptr指针指向的堆内存空间的引用计数为 1,如果unique_ptr 指针放弃对所指堆内存空间的所有权,那么该空间会被立即释放回收。

那么,什么时候使用unique_ptr呢?简单来说:可以考虑将动态分配的有唯一所有者的资源保存在unique_ptr的实例中。

如何初始化一个std::unique_ptr对象?

方法一:

std::unique_ptr<int> sp(new int(12345));

方法二:

std::unique_ptr<int> sp;
sp.reset(new int(12345));

方法三:

std::unique_ptr<int> sp = std::make_unique<int>(12345);

以上三种方式均可,其中,方法三是C++14新增的,通过std::make_unique方法来创建std::unique_ptr对象。

std::unique_ptr禁止复制语义

和 std::shared_ptr区别:unique_ptr是移动构造(unique_ptr不可拷贝和赋值,但可以被移动,unique_ptr禁止复制语义,拷贝构造函数和复制运算符operator= 均被标记为 =delete),shared_ptr是拷贝构造,伪代码如下:

std::unique_ptr<T> up1 = std::move(up);

std::shared_ptr<T> sp1 = sp; 

unique_ptr 独占所指向的对象,与shared_ptr不同的是,某个时刻只能有一个unique_ptr指向一个给定对象。当unique_ptr被销毁时,它所指向的对象也被销毁。

禁止复制语义存在特例,比如,可以通过函数得到一个std::unique_ptr对象,然后返回给up即可:

std::unique_ptr<int> clone(int val)
{std::unique_ptr<int> p(new  int(val));return p;
}int main()
{int num =  5;std::unique_ptr<int> up =  clone(num);return 0;
}

std::unique_ptr与std::move不解之缘

std::unique_ptr无法被复制,但可以使用移动构造将std::unique_ptr对象持有的堆内存转移给另外一个对象,简单代码如下:

std::unique_ptr<int> sp(std::make_unique<int>(12345));std::unique_ptr<int> sp1(std::move(sp));

std::move将sp持有的堆内存转移给sp1后,sp不再持有堆内存的引用,变成一个空的智能指针对象。

那么,是不是所有的对象,都可以用std::move操作呢?答案是否定的,只有实现了移动构造函数或移动运算符的类才可以。恰恰std::unique_ptr实现了二者。

使用场景举例

动态申请的资源提供异常安全保障

当我们动态申请内存后,可能会抛出异常或者提前退出,导致没有执行delete操作。

#include<memory>
#include<iostream>
using namespace std;class Func {};int main()
{Func* pFunc =  new Func;/可能抛出异常delete pFunc;return 0;
}

此时使用std::unique_ptr来管理动态内存,只要std::unique_ptr指针创建成功,其析构函数都会被调用,确保动态资源被释放。

#include <memory>
#include<iostream>
using namespace std;class Func{};int main()
{unique_ptr<Func> upFunc(new  Func);//...return 0;
}

容器内保存指针示例:

std::vector<std::unique_ptr<int>> vec;
std::unique_ptr<int> sp(std::make_unique<int>(12345));
vec.push_back(std::move(sp));

篇幅有限,本文权当抛砖引玉,感兴趣的同学,可基于此,做进一步的拓展和探究。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/552986.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++17新特性之try_emplace与insert_or_assign

由于std::map中&#xff0c;元素的key是唯一的&#xff0c;我们经常遇到这样的场景&#xff0c;向map中插入元素时&#xff0c;先检测map指定的key是否存在&#xff0c;不存在时才做插入操作&#xff0c;如果存在&#xff0c;直接取出来使用&#xff0c;或者key不存在时&#x…

Unity环境下实现Camera高帧率RTMP推送

Unity下RTMP直播背景方面不再赘述&#xff0c;今天主要讨论的是&#xff0c;Unity环境下&#xff0c;如何实现Camera高帧率RTMP推送&#xff0c;这里提到的高帧率&#xff0c;不再局限于常规环境下的30帧&#xff0c;以VR头显为例&#xff0c;更高的帧率&#xff08;比如50帧&a…

如何在Android平台GB28181接入终端实现语音广播和语音对讲

技术背景 在之前的blog&#xff0c;我们以Android平台国标接入终端为例&#xff0c;分别介绍了一些常规的功能&#xff0c;比如REGISTER、CATALOG、INVITE、Keepalive、SUBSCRIBE、NOTIFY等常规操作&#xff0c;今天主要介绍下语音广播和语音对讲这部分。 GB28181平台广播和对…

Android GB28181设备接入端语音广播和语音对讲技术实现探究

上篇文章提到Android端GB28181接入端的语音广播和语音对讲的实现&#xff0c;从spec角度大概介绍了下流程和简单的接口设计&#xff0c;好多开发者私信我&#xff0c;希望展开说一下。其实这块难度不大&#xff0c;只是广播和对讲涉及到双向实现&#xff0c;如果之前没有相关的…

Android native层实现MediaCodec编码H264/HEVC

Android平台在上层实现mediacodec的编码&#xff0c;资料泛滥&#xff0c;已经不再是难事&#xff0c;今天给大家介绍下&#xff0c;如何在Android native层实现MediaCodec编码H264/HEVC&#xff0c;网上千篇一律的接口说明&#xff0c;这里不再赘述&#xff0c;本文主要介绍下…

GB/T 28181联网系统通信协议结构和技术实现

技术回顾 在本文开头&#xff0c;我们先一起回顾下GB/T28181联网系统通信协议结构&#xff1a; 联网系统在进行视音频传输及控制时应建立两个传输通道&#xff1a;会话通道和媒体流通道。 会话通道用于在设备之间建立会话并传输系统控制命令&#xff1b;媒体流通道用于传输视…

Android平台GB28181设备接入端对接编码前后音视频源类型浅析

前言 今天主要对Android平台GB28181设备接入模块支持的接入数据类型&#xff0c;做个简单的汇总&#xff1a; 编码前数据&#xff08;目前支持的有YV12/NV21/NV12/I420/RGB24/RGBA32/RGB565等数据类型&#xff09;&#xff0c;其中&#xff0c;Android平台前后摄像头数据&…

C++学习之-析构函数必须为虚函数吗?

今天讨论个比较有意思的话题&#xff1a;析构函数是不是必须要为虚函数&#xff1f; 先说答案&#xff1a; 析构函数可以是虚函数&#xff0c;也可以不是虚函数。 再说原因&#xff1a; 析构函数为虚函数的情况&#xff1a;继承 当父类指针释放子类对象时&#xff0c;如果…

如何实现RTMP或RTSP播放端回调YUV/RGB数据?

今天某乎收到个问题推荐&#xff0c;如何实现RTSP回调YUV数据&#xff0c;用于二次处理&#xff1f; 正好前些年我们做RTSP和RTMP直播播放的时候&#xff0c;实现过相关的需求&#xff0c;本文就以Android为例&#xff0c;大概说说具体实现吧。 先说回调yuv或rgb这块意义吧&a…

GB28181控制、传输流程和协议接口之注册|注销和技术实现

注册和注销基本要求 SIP客户端、网关、SIP设备、联网系统等 SIP代理(SIP UA)使用IETFRFC3261中定义的方法 15 GB/T28181—2016Register进行注册和注销。 注册和注销时应进行认证&#xff0c;认证方式应支持数字摘要认证方式&#xff0c;高安全级别的宜支持数字证书的认证方式&…

GB28181状态信息报送解读及Android端国标设备接入技术实现

今天主要聊聊GB/T28181状态信息报送这块&#xff0c;先回顾下协议规范相关细节&#xff0c;然后再针对代码实现&#xff0c;做个简单的说明。 状态消息报送基本要求 当源设备(包括网关、SIP设备、SIP客户端或联网系统)发现工作异常时,应立即向本 SIP监控域 的SIP服务器发送状…

GB28181设备接入端如何实现校时?

在探讨这个问题之前&#xff0c;我们先看看GB/T28181-2016官方文档怎么说的&#xff0c;9.10.1章节校时基本要求提到&#xff1a; 联网内设备支持基于SIP方式或 NTP方式的网络校时功能&#xff0c;标准时间为北京时间。 SIP方式校时见本节具体描述&#xff1b;NTP(见IETFRFC2…

如何在Unity下采集音视频实现轻量级RTSP服务(类似于IPC)

好多开发者在做虚拟仿真、VR教育等场景的时候&#xff0c;遇到个问题&#xff0c;想把头显里面的画面在内网环境下低延迟的同步出来&#xff0c;又不想单独部署流媒体服务器。为此&#xff0c;我们在Unity下&#xff0c;添加了轻量级RTSP服务模块&#xff0c;通过头显端启动个轻…

【Datawhale 大模型基础】第十一章 环境影响

第十一章 环境影响 This blog is based on datawhale files and a paper. The initial consideration revolves around the potential positive or negative direct impact on the environment. Other transformative technological advancements, like the metaverse, are li…

Android GB28181接入端实时位置订阅和上报之-如何获取当前经纬度

我们在做Android平台GB28181的时候&#xff0c;其中实时位置(MobilePosition)订阅和上报这块&#xff0c;涉及到实时经纬度的获取&#xff0c;特别是执法记录、车载系统的那个等场景&#xff0c;几乎就是标配。 今天主要是分享一段实时获取位置的代码&#xff1a; /** Camera…

如何实现Android平台GB28181设备对接Camera2数据

技术背景 在写如何实现Android平台GB28181设备对接Camera2数据说明之前&#xff0c;我在前两年的blog就有针对camera2的RTMP直播推送模块做过技术分享&#xff1a; 在Google 推出Android 5.0的时候, Android Camera API 版本升级到了API2(android.hardware.camera2), 之前使用…

Android平台GB28181设备接入端本地SIP端口被占用或屏蔽怎么办?

好多开发者或厂商&#xff0c;对Android平台GB28181接入模块的定位&#xff0c;大多是IPC国标流程打通模拟&#xff0c;基于这个目的&#xff0c;很难按照标准SPEC规范实现Android平台GB28181设备接入&#xff0c;我们在跟第三方国标平台厂商对接时发现&#xff0c;部分公司&am…

Android平台GB28181设备接入端如何实现本地录像?

实现Android平台GB28181设备接入的时候&#xff0c;有个功能点不可避免&#xff0c;那就是本地录像&#xff0c;实际上&#xff0c;在实现GB28181设备接入模块之前&#xff0c;我们前些年做RTMP推送和轻量级RTSP服务的时候&#xff0c;早已经实现了本地录像功能。 本地录像功能…

国网B接口注册(REGISTER)接口描述和消息示例

技术背景 电网视频监控系统是智能电网的一个重要组成部分&#xff0c;广泛应用于电网的建设、生产、运行、经营等方面。由于视频监控系统在不同的建设时期选用了不同的技术和不同厂家的产品&#xff0c;导致了标准不统一、技术路线不一致。目前国家电网公司智能电网建设&#…

国网B接口资源上报(Push_Resourse)接口描述和消息示例

上篇blog&#xff0c;梳理了国网B接口的REGISTER接口描述和消息示例&#xff0c;前端系统加电启动并初次注册成功后&#xff0c;向平台上报前端系统的设备资源信息&#xff08;包括&#xff1a;视频服务器、DVR/DVS、摄像机、告警设备、环境量采集设备等模拟或数字信号采集设备…