C++学习笔记 15 作用域指针(智能指针) unique_ptr、 shared_ptr、weak_ptr

news/2025/12/12 16:01:21/文章来源:https://www.cnblogs.com/guchunchao/p/19334665

一、何为作用域指针

如果栈上的变量会自动消失,那他有什么用呢?有没有其他办法,让他用在好的方面?
答案是有的。他在很多方面都非常有用,可以帮助我们自动化代码。
eg: 其中我们可以做的一件事是,比如说利用类的作用域来实现的,像是智能指针:smart_ptr,或是unique_ptr,这是一个作用域指针
或者像作用域锁。。。。。。有很多例子

最简单的例子就是作用域指针了,它的本质就是一个类,是一个指针的包装器,在构造时再堆上分配指针,然后析构时删除指针。
通过作用域指针,我们可以自动化这个new和delete。

二、自定义作用域指针

三、C++ 作用域指针

unique_ptr、 shared_ptr、weak_ptr
出处: #include

smart pointer | scope pointer

#include<iostream>
#include<memory>class Entity22 {
public:int x;Entity22(): x(0) {std::cout << "Create Entity" << std::endl;}~Entity22() {std::cout << "Destroy Entity" << std::endl;}void Print() {std::cout << x << std::endl;}
};int* CreateArray() {//变量在栈中创建,这样的写法是错误的❌️//int Arr[50];//堆变量可以return给外部int* Arr = new int[50];return Arr;//方法结束,方法栈被释放,方法栈中变量也被释放了,即便return也不能被外部调用,而堆中对象可以
}void createObj() {//栈对象,在当前方法执行完成后,当前方法作用域栈自动被释放,包括此对象,且析构函数自动被执行Entity22* ent;//堆对象,在当前方法执行完成后,当前方法作用域栈自动被释放,但此对象不在栈中,在堆中,不被释放,析构函数不被执行//当手动delete堆对象的时候,才会释放堆中对象,其析构函数才会执行Entity22* entity = new Entity22();std::cin.get();delete entity;
}//如果栈上的变量会自动消失,那他有什么用呢?有没有其他办法,让他用在好的方面?
//答案是有的。他在很多方面都非常有用,可以帮助我们自动化代码
//eg: 其中我们可以做的一件事是,比如说利用类的作用域来实现的,像是智能指针:smart_ptr,或是unique_ptr,这是一个作用域指针
//或者像作用域锁。。。。。。有很多例子
//最简单的例子就是作用域指针了,它的本质就是一个类,是一个指针的包装器,在构造时再堆上分配指针,然后析构时删除指针。
//我们可以自动化这个new和delete。//这就是一个简单的作用域指针(智能指针)
class MyOwnScopePtr {
private:Entity22* m_Ptr;
public:MyOwnScopePtr(Entity22* ptr):m_Ptr(ptr) {}~MyOwnScopePtr() {delete m_Ptr;}
};void test_my_own_smart_ptr() {//e是分配在栈上的,当e被销毁时,调用析构函数,Entity22指针也会被销毁//这种可以自动构造、自动析构、离开作用域之后就自动销毁的栈变量是非常有用的{MyOwnScopePtr e(new Entity22());}
}//C++库 作用域指针1:unique_ptr,不可被拷贝,不可被引用
void test_unique_ptr() {{//unique_ptr是C++14开始支持,不可以被拷贝//0. 此unique_ptr 构造方法是explicit的,不可隐式转换 :std::unique_ptr<Entity22> entity = new Entity22();//1. 智能指针创建方式一,一般不用这种std::unique_ptr<Entity22> entity(new Entity22());//2. 智能指针创建方式二,更好的创建方式//这种实现方式是出于异常安全考虑,这对unique_ptr很重要,你不会因为得到一个没有引用的空指针而导致内存泄漏std::unique_ptr<Entity22> entity2 = std::make_unique<Entity22>();//3. 访问智能指针的方法,属性entity2->Print();std::cout << entity2->x << std::endl;}
}//C++库 作用域指针2:shared_ptr
//共享指针,采用引用计数法:跟踪统计你的指针有多少引用的方法。一旦计数为0,就会被删除。
//shared_ptr会额外分配一块叫做控制块的内存,用来存储引用计数。
void test_shared_ptr() {{std::shared_ptr<Entity22> e0;{//1. 创建方式一,两次内存分配:1. new Entity22; 2. shared_ptr控制块的分配//std::shared_ptr<Entity22> entity(new Entity22());//2. 创建方式二,两次内存分配合并,效率更高std::shared_ptr<Entity22> entity2 = std::make_shared<Entity22>(); //引用计数 +1 = 1e0 = entity2;	//引用计数 +1 = 2//3. 访问智能指针的方法,属性entity2->Print();std::cout << entity2->x << std::endl;} //引用计数-1 = 1} //引用计数 -1 = 0, 释放Entity22的内存空间,调用析构函数std::cin.get();
}//weak_ptr 不会增加引用计数
//不想拥泛型对象的所有权,这非常有用。eg:你在对一个Entity22列表进行排序,但是你并不关心它们是否有效,你只需要存储一个它们的引用就好了。
//可以通过weak_ptr去判断底层对象是否还活着,如果还活着,就去做你想做的事。
// 因为它不会增加引用计数,所以不会保证底层对象一直存活。void test_weak_ptr() {{std::weak_ptr<Entity22> e0;{//错误,不可调用//std::weak_ptr<Entity22> entity(new Entity22());//2. 创建方式二,两次内存分配合并,效率更高std::weak_ptr<Entity22> entity2 = std::make_shared<Entity22>();e0 = entity2; //可以被复制//属性和方法无法被调用//entity2->Print();//std::cout << entity2->x << std::endl;} //此作用域结束时,对象内存被释放了,析构函数被调用。无需等待外层作用域执行完。}std::cin.get();
}//什么时候应该使用只能指针?
//你应该试着一直使用它们。老实说,它们自动化了你的内存管理,它们防止你因为忘记调用delete而导致内存泄漏,
//shared_ptr是有一点开销的,因为它的引用计数系统,
//但是同样,很多人倾向于编写自己的内存管理系统,往往也会有一些开销,所以这是一个非常微妙的话题。
//现在有新一代的C++程序员,他们只使用这些功能,但还有很多人用new 和 delete,
//我有点两者兼而有之,因为有时候你可能只想用unique_ptr或shared_ptr,但有时也需要用new和delete,
//所以,我不认为这完全取代了,new和delete,这只是当你需要声明一个堆分配的对象,并且不是特别想自己来清理,
//因为你不想显示地调用delete和手动管理内存时,这种情况下,你应该使用unique_ptr和shared_ptr,
// 通常可能使用unique_ptr,因为它的开销低。但是如果你需要在对象之间共享,则需要用shared_ptr,
//int main() {//CreateArray();//createObj();test_shared_ptr();
}

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

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

相关文章

上海疫情对出国留学的影响有哪些 - 留学机构评审官

上海疫情对出国留学的影响有哪些一、上海疫情对出国留学的影响有哪些作为从业12年的国际教育规划师,我经常被学生和家长问及区域性事件对留学计划的影响。上海作为中国重要的国际教育枢纽,在疫情期间确实面临了一些挑…

LGV 引理、Cauchy-Binet 定理、Matrix-Tree 定理、BEST 定理

尽管有的证明较为繁琐,学习它们也很有意义。摘一段大佬的博客里的话:为什么要写这个证明呢?周围很多人认为比较浪费时间,一般不考。然而输入感知定理其中的智慧,不仅对于图论、线性代数有了更深入的了解,还可以为…

C++学习笔记 09 构造函数初始化成员变量

注意事项尽量用括号的形式去初始化成员变量,避免成员变量的被多次初始化 括号形式构造成员变量: 顺序需和成员变量定义顺序保持一致#include<iostream>class Entity { public:int m_Score;std::string m_Name;/…

文件外发系统是什么?主要有哪些功能和优势?

文件外发系统是一种专门用于确保安全文件传输的解决方案,适用于企业间的核心数据交换。这种系统不仅仅是一个工具,更是实现数据保护和合规管理的重要手段。通过建立安全的文件传输通道,企业能够有效防止数据泄露和未…

UU跑腿新手骑手一天能接多少单?揭秘“单多不愁”的接单密码与成长路径 - 资讯焦点

UU跑腿新手骑手一天能接多少单?揭秘“单多不愁”的接单密码与成长路径——从日均10单到月入过万的实战指南UU跑腿新手骑手一天能接多少单? "第一天接单,我连导航都找不到,结果只跑了5单,收入才30多块,这怎么…

2025-2026年全自动COD分析仪品牌有哪些?cod分析仪/COD测定仪厂家口碑推荐性价比高的 - 品牌推荐大师1

全自动COD分析仪品牌有哪些?cod分析仪/COD测定仪厂家口碑推荐性价比高 “十四五”生态环境监测规划、重点流域水生态环境保护规划、排污许可制度等政策持续推动COD分析仪在工业废水排放口、污水处理厂、环境监测站等场…

Tencoding with out BOM

TStringList.savetofile使用utf8编码并不需要BOM type TUTF8EncodingNOBOM = class(TUTF8Encoding) public function GetPreamble: TBytes; override; end; { TUTF8EncodingNOBOM } function TUTF8EncodingNOBOM…

基于C#的PLC串口通信实现

一、基础通信配置 1. 串口参数设置 using System.IO.Ports;public class PlcSerial {private SerialPort _serialPort;public PlcSerial(string portName, int baudRate = 9600){_serialPort = new SerialPort{PortNam…

rman+duplicate迁移_RAC-单机

RAC环境: db_name= orcl sid= orcl1/orcl2单实例: db_name= orcl sid= orclRac 网卡设置: 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain l…

2025年储热式净水器工厂推荐榜单:净热机‌/阴阳水‌/千滚水源头工厂精选 - 品牌推荐官

随着消费者对饮水健康与便捷热水需求的“双重升级”,储热式净水器(净热一体机)市场正迎来高速增长期。据行业数据显示,净热一体机已成为净水品类中增长最快的细分赛道之一,尤其在改善“千滚水”、解决家庭“饮、焯…

2025年山东口碑好推广公司机构推荐:诚信的推广公司有哪些? - 工业推荐榜

本榜单依托山东地区B2B工业建材领域真实服务案例与客户口碑调研,深度筛选出五家标杆推广企业,为枣庄、济南、青岛等地区的工业门、玻璃隔断企业选型提供客观依据,助力精准匹配适配的推广服务伙伴。 TOP1 推荐:山东…

某中心科技在疫情与可持续发展中的应用

文章介绍了某中心在2019年股东信中提及的八项科技相关举措,包括利用云计算和大数据追踪疫情、开发诊断工具、使用AI提供健康指导,以及在可再生能源、碳足迹测量和数据中心能效方面的技术实践。2019年,某中心创始人兼…

UU跑腿速度快吗?大概多久能到?——揭秘同城即时配送的“极速密码” - 资讯焦点

急需送文件却担心堵车误事?节日礼物卡点送达怕迟到?UU跑腿究竟多快能送达?作为以“快、靠谱、专业跑腿”为核心竞争力的同城配送平台,UU跑腿通过智能科技与人文服务的双重赋能,实现了从“分钟级响应”到“精准送达…

C++学习笔记 08 const 和 multable

一、const方法 二、指针常量 和常量指针 三、multable修饰变量,使可以在常量方法中被修改修饰lambada表达式,#include<iostream>// 标记, lambada表达式中,访问外部变量数据 void mutableLambadaFunction() …

UU跑腿对骑手管理严吗?有没有强制在线时间?揭秘真正的“时间自由”与无压力接单 - 资讯焦点

你是否也曾向往一份时间完全由自己掌控、收入多劳多得的工作,却又担心陷入严格的在线时长考核与算法的无形压力中?"听说跑腿平台管理很严,要打卡、要上线时间,我有点担心。"——这是许多想加入UU跑腿的骑…

2025年度武汉印刷公司TOP5权威推荐:破解印刷痛点赋能品 - mypinpai

印刷作为企业品牌传播与教育教学实施的核心支撑环节,其品质、时效与性价比直接影响客户的业务推进效率。2024年湖北印刷市场规模突破60亿元,年增速12%,但客户投诉中35%集中在个性化需求难满足交付超时品质不稳定三大…

2025上海出国留学中介哪家靠谱 - 留学机构评审官

2025上海出国留学中介哪家靠谱一、2025年上海出国留学中介选择指南作为一名从事国际教育规划工作超过10年的资深顾问,笔者经常被学生和家长问及:2025年上海地区哪家出国留学中介更靠谱?这个问题的答案往往取决于多个…

2025上海留学机构排行榜 - 留学机构评审官

2025上海留学机构排行榜一、如何找留学中介许多上海的学生和家长在搜索留学中介时,常会问:“2025年上海有哪些靠谱的留学机构?”、“如何根据本地需求选择中介?”。作为从业10年的国际教育规划师,我认为选择中介需…

C++学习笔记 07 字符串

一、默认编码 ASCII ASCII可以拓展为很多,比如UTF-8、UTF-16、 UTF-32 还有宽字符(wide string) 当然,字符其实是可以大于一个字节的,在其他语言中(日语、中文)有两个、三个、四个字节的字符。 二、大小 1字节…

上海10大留学机构实力排名 - 留学机构评审官

上海10大留学机构实力排名一、上海留学机构排名解析许多计划留学的学生和家长在搜索引擎上高频查询“上海留学机构哪家强”、“上海留学中介排名前十”等问题,希望找到可靠的选择。作为从业15年的国际教育规划师,我经…