尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

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

C++学习笔记 15 作用域指针(智能指针) unique_ptr、 shared_ptr、weak_ptr
📅 发布时间:2026/6/19 16:40:11

一、何为作用域指针

如果栈上的变量会自动消失,那他有什么用呢?有没有其他办法,让他用在好的方面?
答案是有的。他在很多方面都非常有用,可以帮助我们自动化代码。
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();
}

相关新闻

  • C++学习笔记 09 构造函数初始化成员变量
  • Tencoding with out BOM
  • 基于C#的PLC串口通信实现

最新新闻

  • 6个免费方法让你的手机视频秒变MP4 - 软件工具教程方法
  • Kali Linux实战:ARP欺骗攻击原理、环境搭建与Wireshark流量分析
  • 杭州靠谱品牌首饰回收排行,光谱验金透明称重全款现结 - 奢品小当家
  • 2026年安徽省合肥市合肥医药卫生学校招生简章官网发布:报名入口+报考指南 - cc江江
  • 武汉钻石回收怎么选?2026年实测合规机构名录 - 薛定谔的梨花猫
  • 机器学习模型上线后如何应对系统性风险与数据漂移

日新闻

  • 5分钟掌握Python进化算法:Geatpy高性能优化工具完全指南
  • Microchip 24AA044 EEPROM选型与应用全指南:从参数解析到实战编程
  • 华为的鸿蒙到底有多牛?为什么称作遥遥领先?

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号