C++——智能指针 auto_ptr
一、RAII思想的引入
#include <iostream>
using namespace std;#if 0
// C++中动态申请的资源需要用户自己手动释放
// 如果操作不当,容易造成内存泄漏
// 能否做到让资源自动被释放:RAII
// RAII : 将资源交给对象管理,对象被销毁时自动调用析构函数可以在析构函数中将资源释放掉template<class T>
class smart_ptr
{
public:smart_ptr(T* ptr = nullptr): _ptr(ptr){}// 具有指针类似的效果T& operator*(){return *_ptr;}T* operator->(){return _ptr;}~smart_ptr(){if (_ptr){delete _ptr;_ptr = nullptr;}}T* Get(){return _ptr;}private:T* _ptr;
};void TestSmartPtr1()
{//int* p = new int(10);//smart_ptr<int> sp(p);// ...//delete p;smart_ptr<int> sp(new int(10));*sp = 100;// ...
}struct A
{int a;int b;int c;
};void TestSmartPtr2()
{smart_ptr<int> sp1(new int(10));*sp1 = 100;smart_ptr<A> sp2(new A());sp2->a = 10;sp2->b = 20;sp2->c = 30;
}// 上述smart_ptr已经很好了,达到了刚开始的需求
// 新的问题:类中涉及到资源的管理时,如果没有显式实现拷贝构造 已经 赋值运算符重载
// 则编译器会以浅拷贝的方式实现,smart_ptr就会有问题
// 解决:能够深拷贝解决吗? 答案:不可以
int main()
{// TestSmartPtr1();TestSmartPtr2();return 0;
}
#endif
二、对于memory库中auto_ptr的使用
// 智能指针:对原生态指针进行了封装,以类的方式管理用户的资源,在析构方法中将资源释放掉
// RAII + 具有指针类似的行为 + 如何解决浅拷贝的问题
// 因此:解决深拷贝方式的不同,实现了不同版本的智能指针// 第一种智能指针
// C++98 auto_ptr 原理:
// RAII + 具有指针类似的行为 + 资源转移来解决浅拷贝问题的
#include <memory>#if 0
class A
{
public:A(){cout << "A::A()" << endl;}~A(){cout << "A::~A()" << endl;}int _a;int _b;
};void TestAutoPtr()
{auto_ptr<A> ap1(new A());ap1->_a = 10;ap1->_b = 20;// 当ap1拷贝构造ap2时,ap1会将自己管理的资源// 转移给ap2,然后ap1不在管理了,即:指向空auto_ptr<A> ap2(ap1);ap2->_a = 100;ap2->_b = 200;// ap1->_a = 10; // 运行崩溃:因为ap1将资源转移走之后指向NULLauto_ptr<A> ap3;// 当ap2给ap3赋值时,ap2会将自己管理的资源// 转移给ap3,然后ap2不在管理资源了,即:指向空ap3 = ap2;A* pa1 = new A();A* pa2 = nullptr;pa2 = pa1;pa1->_a = 10;pa2->_b = 20;
}int main()
{TestAutoPtr();return 0;
}
#endif
三、实现自己自己的auto_ptr
#if 0
namespace bite
{template<class T>class auto_ptr{public:// RAIIauto_ptr(T* ptr = nullptr): _ptr(ptr){}~auto_ptr(){if (_ptr){delete _ptr;_ptr = nullptr;}}// 具有指针类似的行为T& operator*(){return *_ptr;}T* operator->(){return _ptr;}// 资源转移auto_ptr(auto_ptr<T>& ap): _ptr(ap._ptr){ap._ptr = nullptr; 资源转移体现在对用来赋值的旧对象的指针置空} auto_ptr<T>& operator=(auto_ptr<T>& ap){if (this != &ap){if (_ptr) 新对象指针有内容的话,需要先进行置空处理。{delete _ptr;}_ptr = ap._ptr; 利用旧对象指针给新对象指针赋值ap._ptr = nullptr; 同样是对旧对象的指针置空}return *this;}private:T* _ptr;};
}
#endif
四、auto_ptr版本二:加入资源权限的转移
// C++98中auto_ptr的改造:
// RAII + 具有指针类似的行为 + 解决浅拷贝的方式:资管管理权限的转移
// 资管管理权限: 对资源释放的权限namespace bite
{template<class T>class auto_ptr{public:// RAIIauto_ptr(T* ptr = nullptr): _ptr(ptr), _owner(false){if (_ptr){_owner = true;}}~auto_ptr(){if (_ptr && _owner){delete _ptr;_ptr = nullptr;_owner = false;}}// 具有指针类似的行为T& operator*(){return *_ptr;}T* operator->(){return _ptr;}// 资源转移auto_ptr(const auto_ptr<T>& ap): _ptr(ap._ptr), _owner(ap._owner){ap._owner = false;}auto_ptr<T>& operator=(const auto_ptr<T>& ap){if (this != &ap){if (_ptr && _owner){delete _ptr;}_ptr = ap._ptr;_owner = ap._owner;ap._owner = false;}return *this;}private:T* _ptr;mutable bool _owner; // 如果为true,表明该对象具有释放资源的权限};
}class A
{
public:A(){cout << "A::A()" << endl;}~A(){cout << "A::~A()" << endl;}int _a;int _b;
};void TestAutoPtr1()
{bite::auto_ptr<A> ap1(new A());ap1->_a = 10;ap1->_b = 20;// 当ap1拷贝构造ap2时,ap1会将自己管理的资源// 转移给ap2,然后ap1不在管理了,即:指向空bite::auto_ptr<A> ap2(ap1);ap2->_a = 100;ap2->_b = 200;ap1->_a = 10; // 运行成功bite::auto_ptr<A> ap3;// 当ap2给ap3赋值时,ap2会将自己管理的资源// 转移给ap3,然后ap2不在管理资源了,即:指向空ap3 = ap2;A* pa1 = new A();A* pa2 = nullptr;pa2 = pa1;pa1->_a = 10;pa2->_b = 20;delete pa1;
}void TestAutoPtr2()
{bite::auto_ptr<A> ap1(new A());ap1->_a = 10;ap1->_b = 20;if (true){bite::auto_ptr<A> ap2(ap1);ap1->_a = 100;ap2->_b = 200;}// 当if结束时,ap2,退出了自己的程序范围,调用析构函数,ap2将资源释放了// 因此ap1内部的指针就变成了野指针ap1->_a = 1000;ap1->_b = 2000;
}// C++标准建议:在什么情况下都不要使用auto_ptr
int main()
{// TestAutoPtr1();TestAutoPtr2();return 0;
}
相关文章:
C++——智能指针 auto_ptr
一、RAII思想的引入 #include <iostream> using namespace std;#if 0 // C中动态申请的资源需要用户自己手动释放 // 如果操作不当,容易造成内存泄漏 // 能否做到让资源自动被释放:RAII // RAII : 将资源交给对象管理,对象被销毁时自动…...
.Net Framework 4/C# System.IO 命名空间(文件的输入输出)
一、Path 类 Path 类是一个静态类,只能通过类名访问它的静态成员。 获得文件的名字,可以用 GetFileName,返回的是具有扩展名的指定路径字符串的文件名,也可以用 GetFileNameWithoutExtension,返回的是不具有扩展名的指定路径字符串的文件名。 获得文件夹的名字,可以用 G…...
图像分类进阶:从基础到专业 (superior哥AI系列第10期)
图像分类进阶:从基础到专业 🚀 前言 👋 哈喽,各位深度学习的探索者们!我是你们的老朋友superior哥 😎 经过前面九篇文章的学习,相信大家对深度学习的基础概念、神经网络架构、以及训练部署都…...

性能优化之SSR、SSG
一、SSR和SSG介绍 SSR(Server-Side Rendering,服务端渲染)和 SSG(Static Site Generation,静态站点生成)是现代前端框架(如 Next.js、Nuxt.js、Gatsby)的核心渲染策略,用…...
【C语言】字符与字符串
在 C 语言中,字符(Character) 和 字符串(String) 是两个不同但相关的概念。下面详细介绍它们的定义、存储方式和使用方法: 一、字符(Character) 1. 定义与存储 基本类型ÿ…...

经典算法:回文链表
题目:234. 回文链表 给你一个单链表的头节点 head,请你判断该链表是否为 回文链表。如果是,返回 true;否则,返回 false。 示例 1: 输入:head [1,2,2,1] 输出:true示例 2&#x…...

uboot移植之GPIO上电初始状态的调整
开发板在上电之后,GPIO都有一个默认初始状态,这个状态可能是高电平也可能是低电平。而我们的应用程序在正式接管控制这些GPIO,是在内核起来并成功加载根文件系统之后。所以在内核启动的这段时间内,这些GPIO保持在一种不受控的状态…...
PasteForm(ABP)框架之实现更加灵活的类似多租户的归属过滤功能,比如只能查看自己的相关数据
需求说明 在开发中,我们常会遇到一个问题,就是归属查询问题,比如只能查看我自己的,往往这个时候还附带了一个规则,比如有人是在这个规则之外的! 1.只能查看创建者自己创建的资料 2.只能查看我店铺的相关内容,不能查看别人店铺的 3.只能查看我部门的相关信息等 可能你会…...

本地id_rsa.pub输入到服务器~/.ssh/authorized_keys后,依然需要输入密码的解决办法
首先检查服务器: sudo vim /etc/ssh/sshd_config 然后把这两个修改为: 如果依然需要输入密码,在本地终端: ssh -v userserver 查看认证过程,例如我这里提示说明客户端已成功尝试使用密钥认证: 进一步…...

【设计模式-3.7】结构型——组合模式
说明:本文介绍结构型设计模式之一的组合模式 定义 组合模式(Composite Pattern)又叫作整体-部分(Part-Whole)模式,它的宗旨是通过将单个对象(叶子节点)和组合对象(树枝…...

Unity Mac 笔记本操作入门
在 macOS 笔记本电脑上使用 Unity Editor 的场景视图 (Scene View) 旋转视角,主要依赖于触摸板手势和键盘修饰键的组合。由于没有物理中键,操作方式会与 Windows 鼠标略有不同。 以下是具体的旋转视角操作: 1. 基本旋转视角 (Orbit) 这是最…...

实时数据仓库是什么?数据仓库设计怎么做?
目录 一、实时数据仓库是什么 (一)实时数据仓库的定义 (二)实时数据仓库的特点 二、实时数据仓库的应用场景 (一)金融行业 (二)电商行业 (三)物联网行…...

Linux(12)——基础IO(下)
目录 六、重定向 📄输出重定向 📄输入重定向 📄追加重定向 📄dup2 七、理解一切皆文件 八、缓冲区 🧠什么是缓冲区 🧠为什么要引入缓冲区 📄缓冲区类型 九、FILE 六、重定向 我们这…...

WPF可拖拽ListView
1.控件描述 WPF实现一个ListView控件Item子项可删除也可拖拽排序,效果如下图所示 2.实现代码 配合 WrapPanel 实现水平自动换行,并开启拖拽 <ListViewx:Name"listView"Grid.Row"1"Width"300"AllowDrop"True&…...
rocketmq索引
索引的理解 索引是什么, 索引实质是 相同数据的另一种存储结构 我们都知道读和写天然是存在矛盾的, 我们希望写的快,当然是顺序写的性能最高, 顺序写造成数据杂乱无章,没法按照一定的规律去找数。 如果想要找数的效率高, 必须要有结构组织的存放数据, 这样方便按规律找…...

[蓝桥杯]倍数问题
倍数问题 题目描述 众所周知,小葱同学擅长计算,尤其擅长计算一个数是否是另外一个数的倍数。但小葱只擅长两个数的情况,当有很多个数之后就会比较苦恼。现在小葱给了你 nn 个数,希望你从这 nn 个数中找到三个数,使得…...
定时任务的 cron 表达式
定时任务的 cron 表达式 一、什么时 cron 表达式 Cron表达式是一种广泛应用于Linux系统的时间表示格式,常用于定时任务的调度。Cron表达式可以通过指定不同的时间参数,描述一个在 未来某个时间点执行的任务。 二、Cron表达式语法 秒 分 时 日 月 周几…...

【MySQL】 约束
一、约束的定义 MySQL 约束是用于限制表中数据的规则,确保数据的 准确性 和 一致性 。约束可以在创建表时定义,也可以在表创建后通过修改表结构添加。 二、常见的约束类型 2.1 NOT NULL 非空约束 加了非空约束的列不能为 NULL 值,如果可以…...
MySQL 的 redo log 和 binlog 区别?
MySQL 的 redo log 和 binlog 区别? 1. 核心概念对比 1.1 redo log(重做日志) go专栏:https://duoke360.com/tutorial/path/golang 定位:InnoDB引擎层的物理日志作用:实现事务的持久性(ACID中的Durability)记录内容:物理页级别的修改(如"在page 5的offset 10…...

前端vue打开多个窗口,关闭窗口后才继续执行后续逻辑
1.打开第一个弹窗 弹窗的按钮代码 2.点击窗口1中按钮,打开新的窗口 // 请领单按钮点击 async cb_6_delClick() {let ls_yfbm this.st_3Value.BMBMlet pstring {}pstring.a ls_yfbmpstring.b this.queryFormDialog.outDepotDeptCodeawait this.openwithparm_w_md…...

「深度拆解」Spring Boot如何用DeepSeek重构MCP通信层?从线程模型到分布式推理的架构进化
什么是MCP? MCP(Model Context Protocol,模型上下文协议)是由Anthropic公司于2024年11月推出的开放标准协议,旨在为大型语言模型(LLM)与外部数据源、工具及系统提供统一的交互接口,被…...
如何避免在前端项目中出现重复的第三方依赖包?
在现代前端开发中,**重复的第三方依赖包(Duplicate Dependencies)**是导致项目体积膨胀、加载速度变慢、构建时间延长的常见问题。尤其在使用模块打包工具(如 Webpack、Vite、Rollup)时,若项目或其依赖的库…...
Java开发中复用公共SQL的方法
在一次Java后端开发的面试中,面试官问了我一个问题:“你在写代码时会复用公共SQL吗?如果会的话,能详细介绍一下你是如何实现的吗?”这个问题让我眼前一亮,因为在实际项目中,SQL复用确实是一个非…...

【西门子杯工业嵌入式-2-点亮一颗LED】
西门子杯工业嵌入式-2-点亮一颗LED 一、课程回顾与目标1.上节课内容回顾2.本节课目标 二、硬件连接与原理1. 硬件连接方式2. 连接实例 三、GPIO原理知识1. GPIO结构2. 推挽输出模式原理 四、软件实现步骤1. 项目结构设置2. 函数定义3. led.c 文件编写初始化函数 led_init交替闪…...

代码随想录算法训练营第60期第五十五天打卡
大家好,我们今天继续我们图论的部分,其实我们昨天是主要讲解了深搜与广搜的理论基础,我们大体上了解了两种算法的差异与适用情景,今天我们就继续我们的图论的章节,以后几天的题目是图论中比较有名的问题叫做岛屿问题&a…...

重磅更新! 基于Gemini 2.5 Pro打造的AI智能体PlantUML-X上线!
目录 图表绘制AI智能体PlantUML-X上线通过简单的提示词创建各种UML图:轻松搞定其它类型的技术图表: AI智能体PlantUML-X功能实测画一个在Java中的一个简单的用户登录功能的时序图效果展示:根据详细内容生成系统架构图效果展示:效果…...

[5-02-04].第01节:Jmeter环境搭建:
JMeter笔记大纲 Jmeter依赖于JDK,所以必须确保当前计算机上已经安装了JDK,并且配置了环境变量 一、JMeter概述: 1.1.JMeter是什么: JMeter是Appache组织使用java开发的一款测试工具 可以用于对服务器、网络或对象模拟巨大的负载…...

AI智能推荐实战之RunnableParallel并行链
导读:在现代AI应用开发中,如何高效处理多维度数据分析始终是开发者面临的核心挑战。当您需要同时进行情感分析、关键词提取和实体识别,或者要对比多个AI模型的输出结果时,传统的串行处理方式往往效率低下。 本文将深入解析LangCha…...
windows server2019 不成功的部署docker经历
由于现场网络限制,需要将docker 容器部署到windows-server 2019上 1.在windows server 2019上安装 docker-desktop,貌似内核版本太低,无法安装,g 然后曲线救国,window server 2019安装docker,折腾了半天,貌…...

Gemini开源项目DeepResearch:基于LangGraph的智能研究代理技术原理与实现
引言 在人工智能快速发展的今天,如何构建一个能够进行深度研究、自主学习和迭代优化的AI系统成为了技术前沿的重要课题。Gemini开源的DeepResearch一周收获7.9k Star,Google的开源项目Gemini DeepResearch技术通过结合LangGraph框架和Gemini大语言模型&…...