当前位置: 首页 > news >正文

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

相关文章:

  • 探究Vue源码:深入理解diff算法
  • Codeforces Round 950 (Div. 3)
  • Zemax中FFT PSF和惠更斯PSF的区别?
  • GA/T 1400视频汇聚平台EasyCVR级联后,平台显示无通道是什么原因?
  • 【JavaScript脚本宇宙】创造声音的魔法:深入了解Web音频处理库
  • Spring Data Jpa 实现批量插入或更新
  • 【职业思考】程序员应该有什么职业素养?
  • 怎么排查native层的bug
  • DevOps后时代,构建基于价值流的平台化工程
  • f-stack和DPDK
  • hadoop疑难问题解决_NoClassDefFoundError: org/apache/hadoop/fs/adl/AdlFileSystem
  • 强化学习面试题
  • Sui Generis如何为艺术家弥合Web3的鸿沟
  • 详细说说机器学习在交通领域的应用
  • Linux基础指令(一)
  • 【技术性】Search知识
  • 2017 前端面试准备 - 收藏集 - 掘金
  • CAP理论的例子讲解
  • ERLANG 网工修炼笔记 ---- UDP
  • Javascript编码规范
  • js递归,无限分级树形折叠菜单
  • js对象的深浅拷贝
  • PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql
  • spark本地环境的搭建到运行第一个spark程序
  • 来,膜拜下android roadmap,强大的执行力
  • 我建了一个叫Hello World的项目
  • 小程序上传图片到七牛云(支持多张上传,预览,删除)
  • 异常机制详解
  • 智能网联汽车信息安全
  • Nginx实现动静分离
  • Semaphore
  • # Swust 12th acm 邀请赛# [ E ] 01 String [题解]
  • #Z2294. 打印树的直径
  • $L^p$ 调和函数恒为零
  • (2)(2.10) LTM telemetry
  • (NSDate) 时间 (time )比较
  • (全注解开发)学习Spring-MVC的第三天
  • (转)es进行聚合操作时提示Fielddata is disabled on text fields by default
  • (转)关于多人操作数据的处理策略
  • (转)微软牛津计划介绍——屌爆了的自然数据处理解决方案(人脸/语音识别,计算机视觉与语言理解)...
  • .equals()到底是什么意思?
  • .net core webapi 大文件上传到wwwroot文件夹
  • .net 设置默认首页
  • .NET 事件模型教程(二)
  • .net 提取注释生成API文档 帮助文档
  • .NET 中使用 TaskCompletionSource 作为线程同步互斥或异步操作的事件
  • /etc/skel 目录作用
  • @vue/cli脚手架
  • [20161101]rman备份与数据文件变化7.txt
  • [2021 蓝帽杯] One Pointer PHP
  • [2021]Zookeeper getAcl命令未授权访问漏洞概述与解决
  • [8-23]知识梳理:文件系统、Bash基础特性、目录管理、文件管理、文本查看编辑处理...
  • [ASP]青辰网络考试管理系统NES X3.5
  • [BetterExplained]书写是为了更好的思考(转载)
  • [COGS 622] [NOIP2011] 玛雅游戏 模拟