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

检查是否有关联的被管理对象
(公开成员函数)
单对象版本,unique_ptr<T>

operator*operator->

解引用指向被管理对象的指针
(公开成员函数)
数组版本,unique_ptr<T[]>

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

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

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

相关文章

YOLOv8 极简分割代码并输出各类别像素占比

文章目录 前言功能概述必要环境一、代码结构1. 参数定义2. 定义检测器类3. 计算各类别像素占比3.1 遍历每个检测到的目标3.2 获取当前目标的掩码和类别3.3 将掩码转换为整数多边形3.4 创建空白掩码图像并填充多边形3.5 计算掩码像素数3.6 计算掩码多边形的质心3.7 计算像素占比…

中证指数绿色金融

一、 绿色金融问题的方向 问题: 什么是绿色金融&#xff1f; 答案: 绿色金融是指支持环境改善、气候变化缓解和资源效率提升的金融活动&#xff0c;包括绿色信贷、绿色债券、绿色基金等。 问题: 绿色金融与ESG投资有何区别&#xff1f; 答案: ESG投资是一种考虑环境&#xff0…

发光二极管十大品牌

日常电路设计中&#xff0c;LED是必用的元器件之一&#xff0c;辅助判定电路异常。 十大发光二极管品牌-LED灯珠生产厂家哪家好-LED发光二极管厂家前十-Maigoo品牌榜

Zabbix6.0自定义监控项

文章目录 一、自定义监控整体流程二、自定义监控案例1、监控TCP 443端口案例2、监控服务器异地登入(带参监控项) 一、自定义监控整体流程 操作端流程备注Agent端1️⃣ linux&#xff1a;通过命令、脚本取出对应的值2️⃣ linux&#xff1a;根据zbx要求按照格式、编写配置文件、…

Sui Generis如何为艺术家弥合Web3的鸿沟

Sui Generis是一家于3月推出的NFT拍卖行&#xff0c;其联合创始人兼CEO Gab9说其愿景是——更好、更大、更强&#xff01; 表面上看&#xff0c;Sui Generis是备受欢迎的Tombheads NFT拍卖行的重新品牌化&#xff0c;该拍卖行今年早些时候从Fantom区块链迁移出来。但它于3月31…

WooYun-2016-199433 -phpmyadmin-反序列化RCE-getshell

参考资料&#xff1a; Phpmyadmin 脚本/设置.php反序列化漏洞 &#xff08;WooYun-2016-199433&#xff09;复现_phpmyadmin scriptssetup.php 反序列化漏洞-CSDN博客 https://blog.csdn.net/haoxue__/article/details/129368455利用pearcmd.php文件包含拿shell&#xff08;L…

找出链表倒数第k个元素-链表题

LCR 140. 训练计划 II - 力扣&#xff08;LeetCode&#xff09; 快慢指针。快指针臂慢指针快cnt个元素到最后&#xff1b; class Solution { public:ListNode* trainingPlan(ListNode* head, int cnt) {struct ListNode* quick head;struct ListNode* slow head;for(int i …

如何学习Golang语言!

第一部分&#xff1a;Go语言概述 起源与设计哲学&#xff1a;Go语言由Robert Griesemer、Rob Pike和Ken Thompson三位Google工程师设计&#xff0c;旨在解决现代编程中的一些常见问题&#xff0c;如编译速度、运行效率和并发编程。主要特点&#xff1a;Go语言的语法简单、编译…

人体部位眼耳手腿分类数据集4376张4类别

数据集类型&#xff1a;图像分类用&#xff0c;不可用于目标检测无标注文件 数据集格式&#xff1a;仅仅包含jpg图片&#xff0c;每个类别文件夹下面存放着对应图片 图片数量(jpg文件个数)&#xff1a;4376 分类类别数&#xff1a;4 类别名称:["Ears","Eyes&quo…

计算机组成刷题一轮(包过版)

搭配食用 计算机组成原理一轮-CSDN博客 目录 一、计算机系统概述 选择 计算机系统组成 冯诺依曼机 软件和硬件的功能 CPU等概念 计算机系统的工作原理 机器字长 运行速度 求MIPS 编译程序 机器语言程序 平均CPI和CPU执行时间 综合应用 存储程序原理 二…

Python3 笔记:字符串的 replace() 和 expandtabs()

1、replace() 方法把字符串中的 old&#xff08;旧字符串&#xff09; 替换成 new(新字符串)&#xff0c;如果指定第三个参数max&#xff0c;则替换不超过 max 次。 语法&#xff1a;str.replace(old, new[, max]) 参数&#xff1a; old&#xff1a;将被替换的子字符串。 new…

System Verilog实现流水灯

文章目录 一 System Verilog1.1 Systemverilog简介1.2 与verilog的区别1.2.1 两态数据类型&#xff08;1,0&#xff09;1.2.2 枚举类型和用户自定义类型1.2.3 数组与队列1.2.4 字符串1.2.5 结构体和联合体1.2.6 常量1.2.7 过程语句等等 二 流水灯代码三 实验效果总结参考资料 一…

基于睡眠声音评估睡眠质量

随着健康意识的增强&#xff0c;人们越来越关注睡眠质量。确保获得充足的高质量睡眠对于维持身体健康和心理平衡至关重要。专业的睡眠状态测量主要通过多导睡眠图&#xff08;PSG&#xff09;进行。然而&#xff0c;PSG会给受试者带来显著的身体负担&#xff0c;并且在没有专业…

十大人工智能企业

​​​​​​链接&#xff1a;​​​​​​人工智能品牌排行-人工智能十大公司-人工智能十大品牌-Maigoo品牌榜

C# WPF入门学习主线篇(二十一)—— 静态资源和动态资源

C# WPF入门学习主线篇&#xff08;二十一&#xff09;—— 静态资源和动态资源 欢迎来到C# WPF入门学习系列的第二十一篇。在上一章中&#xff0c;我们介绍了WPF中的资源和样式。本篇文章将深入探讨静态资源&#xff08;StaticResource&#xff09;和动态资源&#xff08;Dynam…

借助ChatGPT完成课题申报书中框架思路写作指南

大家好&#xff0c;感谢关注。我是七哥&#xff0c;一个在高校里不务正业&#xff0c;折腾学术科研AI实操的学术人。可以和我&#xff08;yida985&#xff09;交流学术写作或ChatGPT等AI领域相关问题&#xff0c;多多交流&#xff0c;相互成就&#xff0c;共同进步 在课题申报…

数据挖掘--认识数据

数据挖掘--引论 数据挖掘--认识数据 数据挖掘--数据预处理 数据挖掘--数据仓库与联机分析处理 数据挖掘--挖掘频繁模式、关联和相关性&#xff1a;基本概念和方法 数据挖掘--分类 数据挖掘--聚类分析&#xff1a;基本概念和方法 数据对象与属性类型 属性&#xff1a;是一…

[312. 戳气球] 动态规划寻找转移函数

Problem: 312. 戳气球 文章目录 思路Code 思路 这个哥们写的思路真的很牛逼&#xff0c;转载一下他。 戳气球题解 Code class Solution { public:int maxCoins(vector<int>& nums) {nums.insert(nums.begin(), 1);nums.push_back(1);int n nums.size();vector<v…

MySQL免安装版本安装与配置指南

MySQL&#xff0c;作为一款广受欢迎的关系型数据库管理系统&#xff0c;凭借其高效稳定的特点&#xff0c;成为了众多开发者的首选数据存储和查询工具。除了传统的安装版本外&#xff0c;MySQL还提供了免安装版本&#xff0c;为用户提供了快速部署和使用的便利。本文将详细指导…

# log.info(“消息发送成功“); 红色报错 解决方案

log.info(“消息发送成功”); 红色报错 解决方案 一、错误描述&#xff1a; 在使用 idea 创建 maven 项目导入 lombok 依赖时&#xff0c;出现 log.info 报红错误&#xff0c;检查导入依赖正确&#xff0c;网络正常&#xff0c;错误依旧。 二、解决方案&#xff1a; 1、在 i…