c++-智能指针
1、概念
堆内存的对象需要手动使用delete销毁,如果忘记使用delete销毁就会造成内存泄漏。
所以C++在ISO 98标注中引入了智能指针的概念,并在C++11 中趋于完善。
使用智能指针可以让堆内存对象具有栈内存对象的特性。原理时给需要自动回收的堆内存对象套上一层栈内存的模板类对象即可。
C++有四种智能指针:
- auto_ptr (自动指针,已经废弃)(C++ISO 98)
- unique_ptr (唯一指针)(C++ISO 11)
- shared_ptr (共享指针)(C++ISO 11)
- weak_ptr (协助指针)(C++ISO 11)
使用智能指针需要引入头文件#include<memory>
2、auto_ptr
#include <iostream>
#include <memory>
using namespace std;
class Test
{
private:
string s;
public:
Test(string s):s(s)
{
cout << s << "构造函数" << endl;
}
~Test()
{
cout << s << "析构函数" << endl;
}
void show()
{
cout << s << "执行程序" << endl;
}
};
int main()
{
{
Test *t1 = new Test("A");
// 创建一个智能指针管理t1
auto_ptr<Test> ap1(t1); // ap1 管理t1
// 取出被管理的堆内存对象,并调用show成员函数
ap1.get()->show();
// 释放控制权
// ap1.release();
// 创建B堆对象,B将A顶掉,A对象销毁
ap1.reset(new Test("B"));
ap1.get()->show(); // 释放控制权并且销毁资源对象
ap1.reset();
cout << "局部代码块执行结束" << endl;
}
return 0;
}
释放对象不会调用析构函数,只有销毁对象才会有
由于成员变量存在指针类型,因此拷贝构造函数与赋值运算符的使用会出现问题。与浅拷贝的问题不同的是,auto_ptr的复制语义会引起资源对象控制权转移的问题。
#include <iostream>
#include <memory>
using namespace std;
class Test
{
private:
string s;
public:
Test(string s):s(s)
{
cout << s << "构造函数" << endl;
}
~Test()
{
cout << s << "析构函数" << endl;
}
void show()
{
cout << s << "执行程序" << endl;
}
};int main()
{
{
Test *t1 = new Test("A");
// 创建一个智能指针管理t1
auto_ptr<Test> ap1(t1); // ap1 管理t1
auto_ptr<Test> ap2(ap1); // 显式调用拷贝构造函数
cout << ap1.get() << " " << ap2.get() << endl; // 0 0x1052780
auto_ptr<Test> ap3 = ap2; // 隐式调用构造函数
// 0 0 0xe82780
cout << ap1.get() << " " << ap2.get() << " " << ap3.get() << endl;
auto_ptr<Test> ap4;
ap4 = ap3; // 赋值运算符
// 0 0 0 0x922780
cout << ap1.get() << " " << ap2.get() <<
" " << ap3.get() << " " << ap4.get() << endl; }
return 0;
}
3、unique_ptr
作为对auto_ptr的改进,unique_ptr对其他持有的资源对象具有唯一控制权,即不可以通过常规的复制语义转移或拷贝资源对象的控制权。
通过特殊的语法实现控制权的转移效果。
#include <iostream>
#include <memory>using namespace std;class Test
{
private:string s;
public:Test(string s):s(s){
cout << s << "构造函数" << endl;}~Test(){
cout << s << "析构函数" << endl;}void show(){
cout << s << "执行程序" << endl;}
};int main()
{{
Test *t1 = new Test("A");// 创建一个智能指针管理t1unique_ptr<Test> up1(t1); // up1 管理t1unique_ptr<Test> up2(move(up1)); // 显式调用拷贝构造函数
cout << up1.get() << " " << up2.get() << endl; // 0 0x1052780unique_ptr<Test> up3 = move(up2); // 隐式调用构造函数// 0 0 0xe82780
cout << up1.get() << " " << up2.get() << " " << up3.get() << endl;unique_ptr<Test> up4;
up4 = move(up3); // 赋值运算符// 0 0 0 0x922780
cout << up1.get() << " " << up2.get() <<" " << up3.get() << " " << up4.get() << endl;}return 0;
}
4、shared_ptr
unique_ptr对资源具有独占性,多个shared_ptr对象可以共享资源。
shared_ptr有两种创建方式:
两种创建方式的区别在于后者是一步到位(创建资源对象+关系绑定),前者分为两步完成(先创建资源对象,再进行关系绑定)。
新方式的优点:
- 安全性更好
- 性能更好
新方式的缺点:
- 资源释放效率低
每多一个shared_ptr对资源进行管理,引用计数将+1,每个指向该对象的shared_ptr对象销毁时,引用计数-1,最后一个shared_ptr对象销毁时,计数清零,资源对象销毁。
#include <iostream>
#include <memory>
using namespace std;
class Test
{
private:string s;
public:Test(string s):s(s){
cout << s << "构造函数" << endl;}~Test(){
cout << s << "析构函数" << endl;}void show(){
cout << s << "执行程序" << endl;}
};
int main()
{shared_ptr<Test> sp3;{shared_ptr<Test> sp1 = make_shared<Test>("A");
cout << "引用计数:" << sp1.use_count() << endl;shared_ptr<Test> sp2(sp1); // 拷贝构造函数
cout << "引用计数:" << sp2.use_count() << endl; sp3 = sp2;
cout << "引用计数:" << sp3.use_count() << endl;}
cout << "引用计数:" << sp3.use_count() << endl;return 0;
}
5、weak_ptr
weak_ptr是一个不控制资源对象的智能指针,也不会影响资源的引用计数,其主要目的是协助shared_ptr工作。
通过weak_ptr的构造函数,参数传入一个持有资源对象的shared_ptr对象或者weak_ptr对象即可创建。
weak_ptr与资源对象呈现弱相关性,所以不支持get等函数直接操作资源对象。
建议weak_ptr调用lock函数之前,先检测引用计数是否大于0,或使用expried()函数检测是否可以转换为shared_ptr。
lock()函数,通过传入持有资源对象的对象创建新对象
#include <iostream>
#include <memory>
using namespace std;
class Test
{
private:string s;
public:Test(string s):s(s){
cout << s << "构造函数" << endl;}~Test(){
cout << s << "析构函数" << endl;}void show(){
cout << s << "执行程序" << endl;}
};
int main()
{weak_ptr<Test> wp3;{shared_ptr<Test> sp1 = make_shared<Test>("A");weak_ptr<Test> wp1 = sp1;
cout << sp1.use_count() << endl; // 1
cout << wp1.use_count() << endl; // 1weak_ptr<Test> wp2(wp1); // 拷贝构造
cout << wp2.use_count() << endl;shared_ptr<Test> sp2 = wp1.lock();
cout << sp2.use_count() << endl; // 2 wp3 = wp2;
cout << wp3.use_count() << endl;}
cout << wp3.use_count() << endl; // 0if(wp3.expired()){
cout << "无法使用lock函数,因为没有可以管理的对象" << endl;}return 0;
}
相关文章:

c++-智能指针
1、概念 堆内存的对象需要手动使用delete销毁,如果忘记使用delete销毁就会造成内存泄漏。 所以C在ISO 98标注中引入了智能指针的概念,并在C11 中趋于完善。 使用智能指针可以让堆内存对象具有栈内存对象的特性。原理时给需要自动回收的堆内存对象套上一层…...

烟花燃放如何管控?智能分析网关V4烟火检测保障烟火安全
一、方案背景 随着元旦佳节的热潮退去,春节也即将来临,在众多传统的中国节日里,烟花与烧纸祭祀都是必不可少的,一方面表达了人们对节日的庆祝的期许,另一方面也是一种对故者思念的寄托。烟花爆竹的燃放不仅存在着巨大的…...
Vue实现版本号输入、删除时光标自动移动到上、下一个输入框前端demo
前言 首先声明,我平时的工作主要是后端JAVA开发,该demo为前端练习,记录一下劳动成果,希望对大家有所帮助,如果有写的不妥的地方,欢迎大家指正,一起学习、共同进步。 背景 手机验证码、银行卡…...
【胖虎的逆向之路】Android自制Https证书实现双向认证
Android自制Https证书实现双向认证 1.基本概念1.1 HTTP1.2 HTTPS1.3 加密方式1.3.1 对称加密1.3.2 非对称加密 1.4 SSL 功能1.4.1 客户对服务器的身份认证1.4.2 服务器对客户的身份认证1.4.3 建立服务器与客户之间安全的数据通道 1.5 CA 证书 2.证书生成2.1 生成根证书…...
解析千兆多模光模块SFP-GE-SX
千兆多模光模块是一种基于光纤通信的光电转换模块,具有千兆(Gigabit)级别的传输速率。本文将对千兆多模光模块的定义、传输距离、参数、及其应用领域等进行详细介绍。 一、千兆多模光模块SFP-GE-SX是什么? 千兆多模光模块SFP-GE-S…...

Go语言基础简单了解
文章目录 前言关于Go学习流程 基础语法注释变量常量数据类型运算符fmt库 流程控制if、switch、selectfor、break、continue遍历String 函数值传递和引用传递deferinit匿名、回调、闭包函数 数组和切片Map结构体自定义数据类型接口协程和channel线程锁异常处理泛型文件读取文件写…...
kafka重平衡经验总结
文章目录 概要背景解决方法技术细节小结 概要 关于kafka重平衡问题在实践工作的应用 背景 重平衡包括以下几种场景: 消费者组内成员发生变更,这个变更包括了增加和减少消费者。注意这里的减少有很大的可能是被动的,就是某个消费者崩溃退出了主题的分…...
Py之jupyter_client:jupyter_client的简介、安装、使用方法之详细攻略
Py之jupyter_client:jupyter_client的简介、安装、使用方法之详细攻略 目录 jupyter_client的简介 jupyter_client的安装 jupyter_client的使用方法 1、基础用法 (1)、获取内核信息 (2)、执行代码块 (3)、远程执行代码 jupyter_client的简介 jupyter_client 包含 Jupyter 协…...

61.网游逆向分析与插件开发-游戏增加自动化助手接口-游戏红字公告功能的逆向分析
内容来源于:易道云信息技术研究院VIP课 上一节内容:游戏公告功能的逆向分析与测试-CSDN博客 码云地址(master分支):https://gitee.com/dye_your_fingers/sro_-ex.git 码云版本号:63e04cc40f649d10ba2f4f…...
neo4j查询语言Cypher详解(五)--apoc
APOC (Awesome Procedures on Cypher)是一个Neo4j库,它提供了对其他过程和函数的访问,扩展了Cypher查询语言的使用。 apoc MATCH (n:Movie) CALL apoc.create.addLabels( n, [ n.genre ] ) YIELD node REMOVE node.genre RETURN node;附录 参考 apoc…...

odoo17 | 视图操作按钮
前言 到目前为止,我们主要通过声明字段和视图来构建我们的模块。在上一章中,我们刚刚通过计算字段和onchanges引入了业务逻辑。在任何真实的业务场景中,我们都会希望将一些业务逻辑链接到操作按钮。在我们的房地产示例中,我们希望…...

KBDPL.DLL文件丢失,软件游戏无法启动,修复方法
不少小伙伴,求助说遇到Windows弹窗提示“KBDPL.DLL文件丢失,应用无法启动的问题”,不知道应该怎么修复? 首先,先来了解“KBDPL.DLL文件”是什么? kbdpl.dll是Windows操作系统的一部分,是一个动…...
Webpack5 常用优化总结
本文主要总结经常用到的一些代码性能优化、减小代码体积、提升webpack打包构建速度等内容的方法。具体的实现可参考webpack官网查看相关示例。 注:如果读者还未接触过webpack,请先了解webpack的基本使用。 正文: SourceMap ---- 提升开发体…...
Oracle-视图与索引
视图 简介 视图是一种虚表 视图建立在已有表的基础上,视图赖以建立的的这些表成为基表 向视图提供的数据的内容的语句的select 语句,可以将视图理解为存储起来的select 语句 视图向用户提供基表数据的另外一种表现形式 视图的好处 控制数据访问 …...

在Linux写自己的第一个程序“hello Linux”
01.nano指令 我们在Windows中有很多的编译环境,大家应该都很熟悉,但是在Linux中,我们怎么写代码呢? 这里,我介绍一个非常简单的指令->nano 这个指令就类似于我们Windows中的记事本,使用方法也很简单 …...

【AI视野·今日Robot 机器人论文速览 第六十八期】Tue, 2 Jan 2024
AI视野今日CS.Robotics 机器人学论文速览 Tue, 2 Jan 2024 Totally 12 papers 👉上期速览✈更多精彩请移步主页 Daily Robotics Papers Edge Computing based Human-Robot Cognitive Fusion: A Medical Case Study in the Autism Spectrum Disorder Therapy Author…...

图像识别快速实现
文本的跑通了,接下来玩玩图片场景 1. 引入模型 再另起类test_qdrant_img.py,转化图片用到的模型和文本不太一样,我们这里使用ResNet-50模型 import unittest from qdrant_client.http.models import Distance, VectorParams from qdrant_cl…...

一文详解动态 Schema
在数据库中,Schema 常有,而动态 Schema 不常有。 例如,SQL 数据库有预定义的 Schema,但这些 Schema 通常都不能修改,用户只有在创建时才能定义 Schema。Schema 的作用是告诉数据库使用者所希望的表结构,确保…...
Web网页开发-总结笔记2
28.为什么会出现浮动?浮动会带来哪些问题? 1)为什么会出现浮动: 为了页面排版时块元素同行显示 2)浮动带来的问题: 父元素高度崩塌29.清除浮动的方法 (额外标签法、父级overflow、after伪元素、双伪元素) (…...
C#的StringBuilder方法
一、StringBuilder方法 StringBuilder方法Append()向此实例追加指定对象的字符串表示形式。AppendFormat()向此实例追加通过处理复合格式字符串(包含零个或更多格式项)而返回的字符串。 每个格式项都由相应的对象自变量的字符串表示形式替换。AppendJoi…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...

【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...

高抗扰度汽车光耦合器的特性
晶台光电推出的125℃光耦合器系列产品(包括KL357NU、KL3H7U和KL817U),专为高温环境下的汽车应用设计,具备以下核心优势和技术特点: 一、技术特性分析 高温稳定性 采用先进的LED技术和优化的IC设计,确保在…...

python基础语法Ⅰ
python基础语法Ⅰ 常量和表达式变量是什么变量的语法1.定义变量使用变量 变量的类型1.整数2.浮点数(小数)3.字符串4.布尔5.其他 动态类型特征注释注释是什么注释的语法1.行注释2.文档字符串 注释的规范 常量和表达式 我们可以把python当作一个计算器,来进行一些算术…...
基于 HTTP 的单向流式通信协议SSE详解
SSE(Server-Sent Events)详解 🧠 什么是 SSE? SSE(Server-Sent Events) 是 HTML5 标准中定义的一种通信机制,它允许服务器主动将事件推送给客户端(浏览器)。与传统的 H…...