memory动态内存管理学习之unique_ptr
此头文件是动态内存管理库的一部分。std::unique_ptr 是一种智能指针,它通过指针持有并管理另一对象,并在 unique_ptr 离开作用域时释放该对象。在发生下列两者之一时,用关联的删除器释放对象:
- 管理它的
unique_ptr对象被销毁。 - 通过 operator= 或 reset() 赋值另一指针给管理它的
unique_ptr对象。
成员函数
| (构造函数) | 构造新的 unique_ptr(公开成员函数) |
| (析构函数) | 析构所管理的对象,如果存在的话 (公开成员函数) |
| operator= | 为 unique_ptr 赋值(公开成员函数) |
修改器 | |
| release | 返回一个指向被管理对象的指针,并释放所有权 (公开成员函数) |
| reset | 替换被管理对象 (公开成员函数) |
| swap | 交换被管理对象 (公开成员函数) |
观察器 | |
| get | 返回指向被管理对象的指针 (公开成员函数) |
| get_deleter | 返回用于析构被管理对象的删除器 (公开成员函数) |
| operator bool | 检查是否有关联的被管理对象 (公开成员函数) |
单对象版本, | |
| operator*operator-> | 解引用指向被管理对象的指针 (公开成员函数) |
数组版本, | |
| operator[] | 提供到被管理数组的有索引访问 (公开成员函数) |
代码示例:
#include <iostream>
#include <memory>// unique_ptr deleter with state
class state_deleter {int count_;
public:state_deleter():count_(0) {}template<class T>void operator()(T* p) {std::cout << "[deleted #" << ++count_ << "]\n";delete p;}
};struct C{int a;int b;
};int main()
{// unique_ptr constructor examplestd::default_delete<int> d;std::unique_ptr<int> u1;std::unique_ptr<int> u2(nullptr);std::unique_ptr<int> u3(new int);std::unique_ptr<int> u4(new int, d);std::unique_ptr<int> u5(new int, std::default_delete<int>());std::unique_ptr<int> u6(std::move(u5));std::unique_ptr<int> u7(std::move(u6));std::unique_ptr<int> u8(std::auto_ptr<int>(new int));std::cout << "u1: " << (u1 ? "not null" : "null") << '\n';std::cout << "u2: " << (u2 ? "not null" : "null") << '\n';std::cout << "u3: " << (u3 ? "not null" : "null") << '\n';std::cout << "u4: " << (u4 ? "not null" : "null") << '\n';std::cout << "u5: " << (u5 ? "not null" : "null") << '\n';std::cout << "u6: " << (u6 ? "not null" : "null") << '\n';std::cout << "u7: " << (u7 ? "not null" : "null") << '\n';std::cout << "u8: " << (u8 ? "not null" : "null") << '\n';// unique_ptr destructor exampleauto deleter = [](int *p) {delete p;std::cout << "deleter called\n";};std::unique_ptr<int, decltype(deleter)> foo(new int, deleter);std::cout << "foo " << (foo ? "is not" : "is") << " empty\n";// unique_ptr::operator= examplestd::unique_ptr<int> foo2;std::unique_ptr<int> bar2{ nullptr };foo2 = std::unique_ptr<int>(new int(101)); // rvaluebar2 = std::move(foo2); // using std::movestd::cout << "foo2: ";if (foo2)std::cout << *foo2 << '\n';elsestd::cout << "empty\n";std::cout << "bar2: ";if (bar2)std::cout << *bar2 << '\n';elsestd::cout << "empty\n";// unique_ptr::get vs unique_ptr::release//foo3 bar3 p3std::unique_ptr<int> foo3; //nullstd::unique_ptr<int> bar3; //null nullint *p3 = nullptr; //null null nullstd::cout << "foo3: ";if(foo3) std::cout << *foo3 << '\n';else std::cout << "(null)\n";std::cout << "bar3: ";if(bar3) std::cout << *bar3 << '\n';else std::cout << "(null)\n";std::cout << "p3: ";if(p3) std::cout << *p3 << '\n';else std::cout << "(null)\n";std::cout << '\n';foo3 = std::unique_ptr<int>(new int(10)); //(10) null nullbar3 = std::move(foo3); //null (10) nullp3 = bar3.get(); //null (10) (10)*p3 = 20; //null (20) (20)p3 = nullptr; //null (20) nullstd::cout << "foo3: ";if (foo3) std::cout << *foo3 << '\n';else std::cout << "(null)\n";std::cout << "bar3: ";if (bar3) std::cout << *bar3 << '\n';else std::cout << "(null)\n";std::cout << "p3: ";if (p3) std::cout << *p3 << '\n';else std::cout << "(null)\n";std::cout << '\n';foo3 = std::unique_ptr<int>(new int(30)); //(30) (20) nullp3 = foo3.release(); //null (20) (30)*p3 = 40; //null (20) (40)std::cout << "foo3: ";if (foo3) std::cout << *foo3 << '\n';else std::cout << "(null)\n";std::cout << "bar3: ";if (bar3) std::cout << *bar3 << '\n';else std::cout << "(null)\n";std::cout << "p3: ";if (p3) std::cout << *p3 << '\n';else std::cout << "(null)\n";std::cout << '\n';delete p3; // unique_ptr::get_deleter examplestate_deleter del;std::unique_ptr<int> p; //使用默认的deleter;// alpha and beta use independent copies of the deleter:std::unique_ptr<int, state_deleter> alpha(new int);std::unique_ptr<int, state_deleter> beta(new int, alpha.get_deleter());// gamma and delta share the deleter "del" (deleter type is a reference!):std::unique_ptr<int, state_deleter&> gamma(new int, del);std::unique_ptr<int, state_deleter&> delta(new int, gamma.get_deleter());std::cout << "resetting alpha..."; alpha.reset(new int);std::cout << "resetting beta..."; beta.reset(new int);std::cout << "resetting gamma..."; gamma.reset(new int);std::cout << "resetting delta..."; delta.reset(new int);std::cout << "calling gamma/delta deleter...\n";gamma.get_deleter() = state_deleter();//新的deleter// additional deletions when unique_ptr objects reach out of scope (in inverse order of declaration)// example of unique_ptr::operator boolstd::unique_ptr<int> foo4;std::unique_ptr<int> bar4(new int(12));if(foo4) std::cout << "foo4 points to " << *foo4 << '\n';else std::cout << "foo4 is empty\n";if(bar4) std::cout << "bar4 points to " << *bar4 << '\n';else std::cout << "bar4 is empty\n";// unique_ptr::swap examplestd::unique_ptr<int> foo5(new int(10));std::unique_ptr<int> bar5(new int(20));std::cout << "foo5:" << *foo5 << '\n';std::cout << "bar5:" << *bar5 << '\n';foo5.swap(bar5);std::cout << "foo5:" << *foo5 << '\n';std::cout << "bar5:" << *bar5 << '\n';// unique_ptr::operator*std::unique_ptr<int> foo6(new int);std::unique_ptr<int> bar6(new int(100));std::cout << "foo6: " << *foo6 << '\n';std::cout << "bar6: " << *bar6 << '\n';*foo6 = *bar6 * 2;std::cout << "foo6: " << *foo6 << '\n';std::cout << "bar6: " << *bar6 << '\n';// unique_ptr::operator->std::unique_ptr<C> foo7(new C);std::unique_ptr<C> bar7;foo7->a = 10;foo7->b = 20;bar7 = std::move(foo7);if (foo7) std::cout << "foo7: " << foo7->a << ' ' << foo7->b << '\n';if (bar7) std::cout << "bar7: " << bar7->a << ' ' << bar7->b << '\n';// unique_ptr::operator[]std::unique_ptr<int[]> foo8(new int[5]);for (int i = 0; i < 5; ++i) foo8[i] = i;for (int i = 0; i < 5; ++i)std::cout << foo8[i] << ' ';std::cout << '\n';return 0;
}
运行效果:

参考:
https://cplusplus.com/reference/memory/
https://zh.cppreference.com/w/cpp/header/memory
相关文章:
memory动态内存管理学习之unique_ptr
此头文件是动态内存管理库的一部分。std::unique_ptr 是一种智能指针,它通过指针持有并管理另一对象,并在 unique_ptr 离开作用域时释放该对象。在发生下列两者之一时,用关联的删除器释放对象: 管理它的 unique_ptr 对象被销毁。…...
1、项目介绍:为什么要做此项目。
项目介绍:为什么要做此项目。 全栈开发博客实战项目:前后端开发流程以及项目部署 随着互联网的蓬勃发展,全栈开发成为了越来越受欢迎的趋势。前端开发和后端开发之间的紧密合作和协同工作已经成为了现代软件开发中的重要组成部分。然而&…...
2024年6月7日第十五周下午学习英语六级大纲
下午学习英语六级大纲的内容可以归纳为以下几个主要方面: 一、考试概述 六级考试的对象:修完大学英语相应阶段课程的在校大学生。考试目的:参照《大学英语教学指南》设定的教学目标,对我国大学生英语综合运用能力进行科学测量&a…...
每日5题Day19 - LeetCode 91 - 95
每一步向前都是向自己的梦想更近一步,坚持不懈,勇往直前! 第一题:91. 解码方法 - 力扣(LeetCode) class Solution {public int numDecodings(String s) {int n s.length();//注意我们dp的范围是n1int[] d…...
wordpress里面嵌入哔哩哔哩视频的方法
我们正常如果从blibli获取视频分享链接然后在wordpress里面视频URL插入,发现是播放不了的 而视频嵌入代码直接粘贴呢窗口又非常的小 非常的难受,就需要更改一下代码。你可以在在allowfullscreen"true"的后面,留1个空格ÿ…...
Linux系统管理磁盘管理004
本章主要讲述详细lvm扩容。 操作系统: CentOS Stream 9 扩容目标: jianglv扩容到600MB 扩容前 [rootlocalhost ~]# lvdisplay lgb--- Logical volume ---LV Path /dev/lgb/nginx_lvmLV Name nginx_lvmVG Name …...
Flink窗口理论到实践
Flink窗口理论到实践可以分为以下几个关键部分进行阐述: 一、理论概述 窗口概念: Flink窗口是将无限流数据流切分为有限的、连续的数据块进行处理的一种机制。这有助于更高效、更方便地处理无界数据流。窗口分类: 时间窗口:基于固定时间段内收集数据,并在结束时生成结果。…...
279 基于matlab的粒子群集法对铁路电能质量控制系统的容量避行优化设计
基于matlab的粒子群集法对铁路电能质量控制系统的容量避行优化设计。计算出满足功率因素、电压不平衡度等电能指标的条件下。RPC所需要的补偿功率。求得所需最小的系统客量。该设计能快速计算出符合系统设定指标的各项最优补偿功率。并通过sumulink份真。检验设计参数的准确性。…...
46-3 护网溯源 - 溯源报告编写
格式 1. 基本情况︰钓鱼邮件情况介绍 在这部分,需要详细描述钓鱼邮件的基本情况,包括收到的邮件内容、寄件人信息、邮件附件或链接等。还需说明收到邮件的时间和频率。2. 行为分析 详细阐述攻击者的行为模式和攻击方式,包括攻击手段、使用的恶意工具或技术,以及可能的入侵…...
微服务之基本介绍
一、微服务架构介绍 1、微服务架构演变过程 单体应用架构->垂直应用架构一>分布式架构一>SOA架构-->微服务架构 ① 单体应用架构 互联网早期, 一般的网站应用流量较小,只需一个应用,将所有功能代码都部署在一起就可以&#x…...
嘉立创面板制作不规则图案技巧
首先附上效果图展示: 所需软件:嘉立创EDA(专业版)、photoshop、Adobe Illustrator 嘉立创EDA(专业版): 嘉立创面板绘制很容易上手,只要了解这几个图层的作用便可以做出自己想要的面板。 材料边界层: 代表选⽤的材料…...
如何使用Python中的collections模块提供的数据结构,如deque、Counter、OrderedDict等
Python 的 collections 模块提供了一些额外的数据结构,这些数据结构在内置的数据类型(如列表、字典、集合等)的基础上,增加了额外的功能或优化了性能。下面是如何使用 collections 模块中的 deque、Counter 和 OrderedDict 这三种…...
2024年道路安全员考试题库
2024年道路安全员考试题库 16.根据《中华人民共和国道路运输条例》,关于从事客运经营使用的车辆的规定,下列说法错误的是( )。 A.客运经营者应当使用符合国家规定标准的车辆从事道路运输经营 B.客运经营者应当加强对车辆的维护和检测,确保车辆符合国家规定的技术标准 C.…...
自建 Docker 镜像
本文地址:blog.lucien.ink/archives/547 本文主要参考自:自建Docker 镜像/源加速的方法 1. 简介 最近 Docker Hub 被禁一事引起了不小的波动,在这里简单讲下在这之后应该如何访问公开的 Docker Hub。 2. Cloudflare 2.1 搭建 搭建的前提是…...
php实现抖音小程序支付
开发者发起下单_小程序_抖音开放平台 第一步、抖音小程序发起支付 tt.pay_小程序_抖音开放平台 前端提交订单数据到后端接口,然后使用 tt.pay发起支付 请求参数 属性 类型 必填 说明 order_id string 是 担保交易服务端订单号 order_token string 是 …...
代码审计(1):CVE-2022-4957分析及复现
0x00漏洞描述: ѕрееdtеѕt iѕ а vеrу liɡhtԝеiɡht nеtԝоrk ѕрееd tеѕtinɡ tооl imрlеmеntеd in Jаvаѕсriрt. Thеrе iѕ а Crоѕѕ-ѕitе Sсriрtinɡ vulnеrаbilitу in librеѕроndеd ѕрееdtеѕt…...
问题:设备管理指标为完好率不低于( ),待修率不高于5%,事故率不高于1%。 #知识分享#经验分享#经验分享
问题:设备管理指标为完好率不低于( ),待修率不高于5%,事故率不高于1%。 A、100% B、95% C、90% D、80% 参考答案如图所示...
【Linux】(六)—— vim编辑器
vim文件编辑器 Vim(Vi Improved)是一个高度可配置的文本编辑器,最初基于UNIX下的Vi编辑器发展而来,广泛用于程序开发和系统管理中。vim编辑器可以只通过终端命令即可编写修改文件,不需要和gedit一样需要打开类似于记事…...
06016传感器原理与应用202207
06016传感器原理与应用202207 选择题(2*11) 1.基本的电子测量系统由四部分组成,即电源、信号调节、显示系统和B(P7) A.分档器 B.传感器 C.处理器 D.采集器 2.热电阻温度计的测量电路采用精度较高的是B&am…...
java web:springboot mysql开发的一套家政预约上门服务系统源码:家政上门服务系统的运行流程
java web:springboot mysql开发的一套家政预约上门服务系统源码:家政上门服务系统的运行流程 家政上门服务系统的优势 服务质量更稳定:由专业的家政人员提供服务,经过严格的培训和筛选。 价格更透明:采用套餐式收费&…...
为VS Code集成GPT-4V视觉能力:VisualChatGPTStudio实战指南
1. 项目概述:当ChatGPT“睁开双眼”如果你和我一样,是个重度依赖ChatGPT进行编程、文档撰写和头脑风暴的开发者,那你一定体验过它的强大与局限。它能写出漂亮的代码片段,解释复杂的概念,但当你指着屏幕上的一个错误说“…...
APK Installer技术解析与实践指南:Windows平台安卓应用部署的革命性方案
APK Installer技术解析与实践指南:Windows平台安卓应用部署的革命性方案 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 在Windows系统上运行安卓应用一直是…...
别让答辩 PPT 拖垮你的毕业季!PaperXie AI 帮你把论文成果 “说清楚”
paperxie-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/AI PPThttps://www.paperxie.cn/ppt/createhttps://www.paperxie.cn/ppt/create 论文查重过了、导师意见改完了,你以为毕业的最后一关只剩答辩?可打开 PPT 的瞬间,很多人…...
Atheon OpenClaw插件:构建Discord Webhook自动化通知系统的核心指南
1. 项目概述与核心价值最近在折腾一个叫 Atheon OpenClaw Plugin 的开源项目,这名字听起来有点酷,是吧?简单来说,这是一个为 Discord 机器人框架 Atheon 设计的插件,核心功能是实现一个“开放之爪”——也就是一个灵活…...
Sora 2 + After Effects 24.4终极联动教程:含LUT自动映射、运动追踪反哺、动态遮罩同步(附独家.jsx插件)
更多请点击: https://intelliparadigm.com 第一章:Sora 2与After Effects 24.4深度整合概览 Adobe After Effects 24.4 正式引入对 OpenAI Sora 2 模型输出格式的原生支持,标志着生成式视频工作流首次在专业后期平台中实现端到端闭环。该整…...
Model2Vec最佳实践:10个技巧让你的嵌入模型又快又好
Model2Vec最佳实践:10个技巧让你的嵌入模型又快又好 【免费下载链接】model2vec Fast State-of-the-Art Static Embeddings 项目地址: https://gitcode.com/gh_mirrors/mo/model2vec Model2Vec是一个革命性的静态嵌入模型技术,它能将任何句子转换…...
加州DMV十年自动驾驶报告深度解析:从测试数据看行业格局与技术演进
1. 项目概述:一份数据,十年自动驾驶风云如果你关注自动驾驶,那你一定听说过加州车管局(DMV)的年度测试报告。这玩意儿,可以说是全球自动驾驶行业的“晴雨表”和“成绩单”。从2015年开始,加州就…...
告别esptool失败!用乐鑫官方Flash工具给ESP8266刷MicroPython固件(保姆级图文)
ESP8266刷机新选择:乐鑫官方Flash工具全流程指南 为什么选择官方工具替代esptool? 每次看到命令行里跳出的红色报错信息,是不是有种想把开发板扔出窗外的冲动?"端口不存在"、"擦除失败"、"权限不足"…...
3大核心模块+5步实战指南:Betaflight飞控固件深度解析与配置方案
3大核心模块5步实战指南:Betaflight飞控固件深度解析与配置方案 【免费下载链接】betaflight Open Source Flight Controller Firmware 项目地址: https://gitcode.com/gh_mirrors/be/betaflight Betaflight作为开源飞控固件的标杆,为多旋翼和固定…...
华为OD机试真题 新系统 2026-05-06 JavaGoC语言 实现【匹配命令行前缀关键字】
目录 题目 思路 Code 题目 给定一组命令行字符串和一个命令前缀,需要找出所有以前缀开头的命令行表达式中,前缀之后的第一个关键字,并将这些关键字按字典序排序后返回。 如果找不到匹配前缀则返回空;匹配出多个相同关键字时只返…...
