弱引用与C++智能指针

笔试题遇到了弱引用,但是C++标准库是没有这个概念的,学了智能指针但是没有听说过弱引用,因此总结一下两者
学习视频链接来自B站

https://www.bilibili.com/video/BV1gV4y1G7fH?p=2&vd_source=fa4ef8f26ae084f9b5f70a5f87e9e41b

智能指针

C++的对象本质上都需要调用delete来释放,当代码多起来时,总会有忘记手动delete的时候。因此C++提供了智能指针方便程序员。

unique_ptr

使用前需要导入memory头文件,unique_ptr只能单独管理一个对象,因此它的拷贝构造和=运算符被禁用,所以也不能进行值传递,nullptr也重载解引用运算,可以像普通指针一样通过*来访问

#include <iostream>
#include <memory>
using namespace std;
class A {
public:
	string m_Name;
	A() { cout << "这是A类的默认构造函数" << endl; }
	A(string name)
	{
		this->m_Name = name;
		cout << "这是A类的有参构造函数" << endl;
	}
	~A()
	{
		cout << "string  = " << m_Name << "这是A类的析构函数" << endl;
	}
};

int main()
{
	A* p = new A("Tom");
	//unique_ptr指针管理普通指针,unique_ptr指针本身也有自己的地址,第一种初始化方法
	unique_ptr<A> uPtr1(p);
	//推荐使用这种方法初始化一个智能指针
	unique_ptr<A> uPtr2(new A("Jerry"));
	//C++14语法
	unique_ptr<A> uPtr3 = make_unique<A>("Jack");
	return 0;
}

在这里插入图片描述
注:unique_ptr编译器上做了特殊的处理
1.将一个临时的unique_ptr赋值给另一个时(局部变量),编译器是允许这么做的;若unique_ptr已经管理了一个指针,那么它会先释放原本管理的指针,再去管理这个临时的unique_ptr,若这个变量长期存在(全局变量),那么这个操作是不允许的。原本的重载运算符=已经被禁用了,依然能接受赋值操作,非常神奇
**2.用nullptr给unique_ptr赋值将对象释放,空的unique_ptr == nullptr **
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
第九点贴图
在这里插入图片描述

shared_ptr

大体上与前一种智能指针一致,但是一个是独享,一个是共享,因此没有禁用拷贝构造和重载=
共享不是赋值,shared_ptr管理的原始指针只有一份
在这里插入图片描述
特别注意
指向资源的引用计数多一个,计数值就 + 1,指向资源的引用计数少一个,计数值就 - 1
在这里插入图片描述
3 4同unique_ptr
在这里插入图片描述
注意:
unique_ptr可以转换为shared_ptr,但是反过来不行
在这里插入图片描述
在这里插入图片描述

#include <iostream>
#include <memory>
using namespace std;
class A {
public:
	string m_Name;
	A() { cout << "这是A类的默认构造函数" << endl; }
	A(string name)
	{
		this->m_Name = name;
		cout << "这是A类的有参构造函数" << endl;
	}
	~A()
	{
		cout << "string  = " << m_Name << "这是A类的析构函数" << endl;
	}
};
void test01()
{
	A* p = new A("Tom");
	//unique_ptr指针管理普通指针,unique_ptr指针本身也有自己的地址,第一种初始化方法
	unique_ptr<A> uPtr1(p);
	//推荐使用这种方法初始化一个智能指针
	unique_ptr<A> uPtr2(new A("Jerry"));
	//C++14语法
	unique_ptr<A> uPtr3 = make_unique<A>("Jack");
	cout << "解引用运算符返回对象的属性," << "A类的名字为:" << (*uPtr2).m_Name << endl;
	cout << "get方法返回管理的裸指针," << "A类的名字为:" << uPtr2.get()->m_Name << endl;
}
void test02()
{
	A* p = new A("Tom");
	//shared_ptr推荐使用这种方式初始化
	shared_ptr<A> sPtr = make_shared<A>("Jack");
	cout << "解引用运算符返回对象的属性," << "A类的名字为:" << (*sPtr).m_Name << endl;
	cout << "shared_ptr的引用计数为:" << sPtr.use_count() << endl; //shared_ptr可以使用这个API返回引用计数值,实际一般不关心具体的值
}

int main()
{
//	test01();
	test02();



	return 0;
}

在这里插入图片描述

智能指针删除器

在这里插入图片描述

share_ptr自定义删除器

在这里插入图片描述

unique_ptr自定义删除器

较为麻烦
在这里插入图片描述

weak_ptr 与弱引用

弱引用概念

AI是这么解释的

"弱引用"在计算机科学中是一个概念,尤其在内存管理和垃圾收集(Garbage Collection)的上下文中。弱引用与强引用相对。当一个对象被强引用时,只要这个引用存在,垃圾收集器就不会回收这个对象。相反,当对象被弱引用时,垃圾收集器会忽略这个引用,并在适当的时候回收这个对象,即使这个弱引用还存在。

弱引用的主要目的是防止内存泄漏,尤其是在需要引用对象但又不想阻止其被垃圾收集器回收的情况下。例如,在缓存系统中,当缓存对象被弱引用时,如果缓存大小超过了限制,垃圾收集器可以回收这些对象,从而避免内存溢出。

更简单的说法
弱引用是一种特殊的引用类型,它允许你引用一个对象,但不会增加该对象的引用计数。这意味着弱引用不会“拥有”对象,也不会阻止对象被垃圾回收器回收。当对象被回收时,弱引用会自动失效,再次访问它会导致错误或异常。
弱引用的主要目的是解决循环引用的问题。在C++中,如果你有两个对象相互引用,即使它们在其他地方都没有被引用,它们也不会被垃圾回收器回收,因为它们相互引用形成了一个“环”。弱引用可以打破这个环,让垃圾回收器能够回收对象。

weak_ptr

没有重载运算符"->"和解引用运算符
在这里插入图片描述
如果对方没死,那么自己不能死,最后谁也没死成
在这里插入图片描述
例子如下

class A {
public:
	string m_Name;
	shared_ptr<B> p;
	A() { cout << "这是A类的默认构造函数" << endl; }
	A(string name)
	{
		this->m_Name = name;
		cout << "这是A类的有参构造函数" << endl;
	}
	~A()
	{
		cout << "string  = " << m_Name << "这是A类的析构函数" << endl;
	}
};
class B {
public:
	string m_Name;
	shared_ptr<A> p;
	~B()
	{
		cout << "析构函数已经被调用" << endl;
	}
};
void test03()
{
	shared_ptr<A> pa = make_shared<A>();
	shared_ptr<B> pb = make_shared<B>();

	pa->p = pb;
	pb->p = pa;
}
int main()
{
//	test01();
//	test02();
	test03();


	return 0;
}

在这里插入图片描述
解决方法,将一个类的shared_ptr改成weak_ptr

#include <iostream>
#include <memory>
using namespace std;
class A;
class B {
public:
	string m_Name;
	weak_ptr<A> p;
	B(string name)
	{
		this->m_Name = name;
		cout << "这是B类的有参构造函数" << endl;
	}
	~B()
	{
		cout << "B类的析构函数已经被调用" << endl;
	}
};
class A {
public:
	string m_Name;
	shared_ptr<B> p;
	A() { cout << "这是A类的默认构造函数" << endl; }
	A(string name)
	{
		this->m_Name = name;
		cout << "这是A类的有参构造函数" << endl;
	}
	~A()
	{
		cout << "string  = " << m_Name << "这是A类的析构函数" << endl;
	}
};

void test01()
{
	A* p = new A("Tom");
	//unique_ptr指针管理普通指针,unique_ptr指针本身也有自己的地址,第一种初始化方法
	unique_ptr<A> uPtr1(p);
	//推荐使用这种方法初始化一个智能指针
	unique_ptr<A> uPtr2(new A("Jerry"));
	//C++14语法
	unique_ptr<A> uPtr3 = make_unique<A>("Jack");
	cout << "解引用运算符返回对象的属性," << "A类的名字为:" << (*uPtr2).m_Name << endl;
	cout << "get方法返回管理的裸指针," << "A类的名字为:" << uPtr2.get()->m_Name << endl;
}
void test02()
{
	A* p = new A("Tom");
	//shared_ptr推荐使用这种方式初始化
	shared_ptr<A> sPtr = make_shared<A>("Jack");
	cout << "解引用运算符返回对象的属性," << "A类的名字为:" << (*sPtr).m_Name << endl;
	cout << "shared_ptr的引用计数为:" << sPtr.use_count() << endl; //shared_ptr可以使用这个API返回引用计数值,实际一般不关心具体的值
}
void test03()
{
	shared_ptr<A> pa = make_shared<A>("Jack");
	shared_ptr<B> pb = make_shared<B>("Tom");

	pa->p = pb;
	pb->p = pa;
}

int main()
{
//	test01();
//	test02();
	test03();


	return 0;
}

在这里插入图片描述
在这里插入图片描述

关键,一般互相配合使用在多线程程序中
在这里插入图片描述
升级的同时加锁pa,pb都是weak_ptr,m_p未指向对方类型的shared_ptr
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C# 中 SQLite 查询数据库表中字段(列)是否存在的方法

查询SQLite数据库表中字段&#xff08;列&#xff09;存在的方法 使用SQL语句为&#xff1a;PRAGMA table_info([DeviceTrees]); 其中“DeviceTrees”为数据库表的名称。 使用SQLite Expert Professional工具&#xff0c;查看该语句是否起作用&#xff0c;这里使用的版本是…

Nest.js权限管理系统开发(三)环境变量与配置文件

一般来说数据库的配置包含了一些敏感信息&#xff0c;不宜写在代码中提交到远程仓库&#xff0c;所以我们可以将配置写在配置文件中,然后提交 git 时候将生产环境的配置文件其忽略。我们可以新建.env和.env.prod两个文件分别存放开发与生产环境配置&#xff0c;也可以使用YAML等…

Linux环境下的性能分析 之 CPU篇(二)

2、CPU的使用情况分析 a、类似任务管理器的top & htop 说到对CPU的性能分析&#xff0c;大家一定不会忘记windows下那个最熟悉的工具&#xff1a;任务管理器。 有了这个玩意儿&#xff0c;我们就可以看到CPU的利用率&#xff0c;以及每一个进程所占用的CPU资源。那在Linu…

【编译原理】第七八章课后习题(王原生第三版)

前言 课本&#xff1a; 编译原理&#xff08;第三版&#xff09;[王生原、董渊…等编著]习题&#xff1a; 主要习题内容是第一章到第八章&#xff0c;具体内容如下表 章节内容链接第一章课后部分选择题https://blog.csdn.net/Zchengjisihan/article/details/136243955第二章课…

瑞_23种设计模式_桥接模式

文章目录 1 桥接模式&#xff08;Bridge Pattern&#xff09;1.1 介绍1.2 概述1.3 桥接模式的结构 2 案例一2.1 需求2.2 代码实现 3 案例二2.1 需求2.1 代码实现 &#x1f64a; 前言&#xff1a;本文章为瑞_系列专栏之《23种设计模式》的桥接模式篇。本文中的部分图和概念等资料…

[Linux]文件基础-如何管理文件

回顾C语言之 - 文件如何被写入 fopen fwrite fread fclose fseek … 这一系列函数都是C语言中对文件进行的操作&#xff1a; int main() {FILE* fpfopen("text","w");char str[20]"write into text";fputs(str,fp);fclose(fp);return 0; }而上…

Stable Diffusion 3震撼发布模型与Sora同架构

Prompt&#xff1a;Epic anime artwork of a wizard atop a mountain at night casting a cosmic spell into the dark sky that says "Stable Diffusion 3" made out of colorful energy Stability AI发布Stable Diffusion 3文本到图像模型。该模型采用扩散变换架构…

ARM处理器有哪些工作模式和寄存器?各寄存器作用是什么?ARM异常中断处理流程?

《嵌入式工程师自我修养/C语言》系列——ARM处理器有哪些工作模式和寄存器&#xff1f;各寄存器作用是什么&#xff1f; 一、ARM处理器的工作模式及寄存器1.1 ARM处理器的工作模式1.2 ARM处理器中的寄存器 二、ARM 异常中断处理2.1 什么是异常&#xff1f;异常向量表是什么&…

Python sorted函数

在Python编程中&#xff0c;sorted()函数是一个内置函数&#xff0c;用于对可迭代对象进行排序。这个函数可以应用于列表、元组、字符串等可迭代对象&#xff0c;并返回一个新的已排序的列表。sorted()函数还提供了一系列的参数&#xff0c;可以实现不同类型的排序&#xff0c;…

服务区智慧公厕

在如今追求智能化、便捷化的社会背景下&#xff0c;高速公路服务区智慧公厕正成为人们关注的焦点。作为高速公路上的必要设施&#xff0c;公厕的提升已经不再局限于简单的清洁卫生&#xff0c;而是更多地涉及到智能化、舒适度和用户体验。本文以智慧公厕源头厂家广州中期科技有…

Autoencoder深度学习中的无监督学习神经网络

在当今的深度学习领域中&#xff0c;自动编码器&#xff08;Autoencoder&#xff09;是一种常见的无监督学习神经网络模型&#xff0c;用于学习有效的数据表示。自动编码器在许多领域都有广泛的应用&#xff0c;包括特征提取、降维、图像去噪、生成模型等。 自动编码器的基本原…

【GPTs分享】GPTs分享之consensus

大家好&#xff0c;元宵节快乐&#xff0c;今天给大家分享的GPTs是consensus。consensu号称无需关键字即可搜索2亿文章&#xff0c;而且给出的链接绝对保真&#xff0c;不再是胡编乱造的&#xff0c;而且能够根据指定主题辅助编写论文或者博客。 简介 consensus使用chat.cons…

Java内部类的使用与应用

内部类的使用与应用 1. 内部类用法 普通内部类&#xff1a; 实例化内部类对象需要先实例化外部类对象&#xff0c;然后再通过OuterClassName.new InnerClassName()方式实例化内部类。内部类对象在创建后会与外部类对象秘密链接&#xff0c;因此无法独立于外部类创建内部类对象…

AutoSAR(基础入门篇)10.8-实验:模式管理

目录 一、配置BswM 二、配置唤醒源 三、配置ComM Users 四、配置BswM的通信控制 五、Service Mapping 首先备份上一次的工程&#xff0c;养成好习惯&#xff08;最好还是用Git&#xff0c;这次最后再安利一下Git这个神器&#xff09;。今天的实验异常的简单&#xff0c;基…

OpenCV Mat实例详解 六

本文将接着OpenCV Mat实例详解继续介绍OpenCV Mat类的操作符及公有成员函数。 Mat & operator Mat & operator (const Mat &m) 将一个Mat对象赋值个另一个Mat对象。 Mat & operator (const MatExpr &expr) 将一个Mat表达式值赋值给Mat对象 Mat & op…

docker打包当前dinky项目

以下是我的打包过程&#xff0c;大家可以借鉴。我也是第一次慢慢摸索&#xff0c;打包一个公共项目&#xff0c;自己上传。 如果嫌麻烦&#xff0c;可以直接使用我的镜像&#xff0c;直接跳到拉取镜像&#xff01; <可以在任何地方的服务器进行拉取> docker打包当前din…

【JMST】:二苄基甲苯作为LOHC加氢以及脱氢性能研究

二苄基甲苯作为液态有机氢载体加氢及其及其脱氢性能的参数研究 摘要&#xff1a;在低压系统下研究了二苄基甲苯&#xff08;H0-DBT&#xff09;的氢化特性。氢化实验在各种金属催化剂上进行&#xff0c;发现 Raney-Ni 催化剂的活性最高。实验均使用 10 克 DBT 和 1 克 Raney-Ni…

使用向量数据库pinecone构建应用04:混合搜索 Hybrid Search

Building Applications with Vector Databases 下面是这门课的学习笔记&#xff1a;https://www.deeplearning.ai/short-courses/building-applications-vector-databases/ Learn to create six exciting applications of vector databases and implement them using Pinecon…

halcon中的一维测量

一维测量 像点到点的距离&#xff0c;边缘对的距离等沿着一维方向的测量都属于1D测量范畴。Halocn的一维测量首先构建矩形或者扇形的ROI测量对象&#xff0c;然后在ROI内画出等距离的、长度与ROI宽度一致的、垂直于ROI的轮廓线&#xff08;profile line&#xff09;的等距线。…

CSP-J 2023 复赛第4题:旅游巴士

【题目来源】https://www.luogu.com.cn/problem/P9751https://www.acwing.com/problem/content/description/5313/【题目描述】 小 Z 打算在国庆假期期间搭乘旅游巴士去一处他向往已久的景点旅游。 旅游景点的地图共有 n 处地点&#xff0c;在这些地点之间连有 m 条道路。 其中…