智能指针入门:深入理解 C++ 的 shared_ptr

文章目录


前言

提示:这里可以添加本文要记录的大概内容:

在 C++ 的开发中,手动管理内存一直是一项易出错的工作。如果你曾因为 new 后忘记 delete 而引发内存泄漏,那你一定会对 C++11 引入的智能指针感激涕零。

今天,我们来聊聊智能指针家族中的"共享型成员 "------std::shared_ptr


提示:以下是本篇文章正文内容,下面案例可供参考

一、什么是 shared_ptr?

shared_ptr 是 C++11 标准库提供的智能指针之一,它通过引用计数 的方式,来自动管理动态分配的内存资源。当最后一个指向对象的 shared_ptr 被销毁时,对象也会被自动释放

简而言之:你不用再手动 delete 了,shared_ptr 会替你做!

🧠先理解"引用计数 "

shared_ptr 背后有个"引用计数器",记录有多少个 shared_ptr 实例在使用这个对象。

每增加一个 shared_ptr 拷贝,计数 +1;

每销毁一个 shared_ptr,计数 -1;

当计数为 0,就自动 delete 对象

二、创建share_ptr

cpp 复制代码
std::shared_ptr<Myclass>ptr1 = std::make_shared<Myclass>()

我们通常用make_share的方式来创建

<>中是指针的类型

右侧()中填参数,这里定义的类Myclass是一个无参,所以我们无参构造就行

三、使用share_ptr

cpp 复制代码
#include<iostream>
#include<memory>

class Myclass
{
public:
	Myclass()
	{
		std::cout << "调用构造函数" << std::endl;
	}

	~Myclass()
	{
		std::cout << "调用析构函数" << std::endl;
	}

	void Say()
	{
		std::cout << "Hello World" << std::endl;
	}
};


int main()
{
	std::shared_ptr<Myclass>ptr1 = std::make_shared<Myclass>();

	{
		std::shared_ptr<Myclass>ptr2 = ptr1;
		ptr2->Say();
		std::cout << "引用计数:" << ptr2.use_count() << std::endl;
	}
	
	std::cout << "引用计数:" << ptr1.use_count() << std::endl;
	return 0;
}

1.输出结果

2.结果分析

首先我们

std::shared_ptrptr1 = std::make_shared();

会调用构造函数,此时ptr1指针指向的是一个堆上创建的 MyClass 对象

然后我们在局部函数中又加入了一个指针ptr2 也是指向ptr1所指向的对象,此时就不会再调用构造函数,而且此时引用计数是2 ,因为有两个指针都指向这个堆上创建的Myclass对象

在局部函数中{},结束后ptr2自动销毁,但不会调用析构函数,因为ptr2销毁了,引用计数-1,还剩下一个,当ptr1销毁后,引用计数为0,此对象才会自动销毁

四、工作原理

shared_ptr 的底层通过一个"控制块"(control block)来记录引用计数 。每当有一个新的 shared_ptr 拷贝或赋值同一块资源,引用计数就会加一;当某个 shared_ptr 销毁时,引用计数减一;当计数归零,资源自动释放

这就像几个人(指针)共同拥有一把钥匙(资源),最后一个人离开时,把钥匙扔掉,锁也解除了

五、注意事项

禁止多个指针管理同一块内存!

cpp 复制代码
MyClass* p = new MyClass();
std::shared_ptr<MyClass> sp1(p);
std::shared_ptr<MyClass> sp2(p); // ❌ 这两行一定不能这样!

用两个 shared_ptr 分别托管了同一块内存

✅ 正确做法只有一种:

让多个 shared_ptr 共享一个控制块,这就要从同一个 shared_ptr 拷贝出来

cpp 复制代码
auto sp1 = std::make_shared<MyClass>();
auto sp2 = sp1; // ✅ 正确,共享控制块,引用计数 +1

六、使用场景

1.多个对象或线程共享同一个资源。

2.比如图形资源管理、网络连接池等场景中,shared_ptr 都能避免复杂的手动内存管理

总结

C++ 是一门强大但复杂的语言,合理使用智能指针可以极大降低内存泄漏和程序崩溃的风险。如果你还在用原始指针管理内存,是时候拥抱智能指针了!

相关推荐
平常心的技术小牛1 小时前
Qt-快速上手-QMenuBar
开发语言·qt
青 春 记 忆2 小时前
零基础入门Python11|Git实战:为任务管理器建立版本历史
开发语言·git·vscode·python·python3.11
余额瞒着我当琳3 小时前
C++--深拷贝三件套 + swap + 写时拷贝 + vector 扩容 + reserve
java·开发语言·c++
坐吃山猪4 小时前
WebClient内存配置解析
开发语言·springboot·webflux
jdksjw4 小时前
同步与异步、阻塞与非阻塞、多线程、协程超详细讲解(Python并发编程从入门到精通)
开发语言·python
Zach_菠萝侠4 小时前
【DeepSeek Harness 研究】进化方向4:安全加固 思考、设计与实现
开发语言·安全·deepseek
ShineWinsu5 小时前
对于C++:布隆过滤器(bloomfilter)的详细解析
c++·面试·位图·位运算·布隆过滤器·海量数据·比特位
SL-staff5 小时前
技术实践:HR如何用JVS-Logic可视化编排实现考勤数据同步(含节点配置与异常处理)
开发语言·python·低代码·钉钉·可视化编排·jvs-logic·hr技术
SomeB1oody6 小时前
【RustyML入门】6.0. 数学工具
开发语言·后端·机器学习·rust·教程
进制树6 小时前
【飞控开发实战·⑲】ROS2无人机开发环境搭建:Jazzy安装、工作空间与hello_drone节点实战
开发语言·安全·无人机·课程设计