C++ 智能指针:unique_ptr、shared_ptr、weak_ptr

本文详细介绍了智能指针的原理和使用,包括shared_ptr、unique_ptr和weak_ptr。智能指针能够自动管理内存,避免内存泄漏。shared_ptr通过引用计数管理内存,当最后一个shared_ptr析构时,内存被释放;unique_ptr拥有唯一所有权,转移所有权时使用移动构造函数;weak_ptr用于解决循环引用问题,不会增加引用计数,可以检测对象是否已被释放。
摘要由CSDN通过智能技术生成

在使用基本指针类型时,需要手动释放指针指向的内存,容易造成内存泄漏。而智能指针类型就是将基本指针类型封装成模板类,以便更好地管理内存。智能指针就是一个,当超出类的作用域时,编译器会自动调用析构函数,自动释放资源,所以智能指针的作用原理就是函数结束时自动释放空间,无需手动释放内存空间。

智能指针的初始化&&赋值

智能指针拥有explicit构造函数,因此普通指针类型不能隐式转换成智能指针,需要显式调用

shared_ptr<int> sp;//定义shared指针
int*p = new int;//定义普通指针
sp = shared_ptr<int>(p); // 显式转换
shared_ptr<int> sp(p); // 显式转换

错误使用:

int*p = new int;//定义普通指针
shared_ptr<int> sp=p;//定义shared指针,隐式转换 ❌

头文件

#include <memory>

unique_ptr指针使用

创建空unique_ptr指针

std::unique_ptr<int> u_p1();
std::unique_ptr<int> u_p2(nullptr);

创建unique_ptr指针,且明确指向

std::unique_ptr<int> u_p3(new int);

创建空unique_ptr指针,且明确指向已经存在的unique_ptr指针内存

std::unique_ptr<int> u_p4(new int);
std::unique_ptr<int> u_p5(std::move(u_p4));//调用移动构造函数
//u_p5 将获取 u_p4 所指堆空间的所有权,而 u_p4 将变成空指针(nullptr)。
std::unique_ptr<int> u_p6(std::u_p5.release());//调用移动构造函数
//u_p5指针释放,u_p6将指向u_p5释放前指向的内存

shared_ptr指针使用

shared_ptr采用引用计数,每一个shared_ptr的拷贝都指向相同的内容,当最后一个shared_ptr析构的时候,内存被释放

创建空shared_ptr指针

std::shared_ptr<int> s_p1();
std::shared_ptr<int> s_p2(nullptr);

创建shared_ptr指针,且明确指向

std::shared_ptr<int> s_p1(new int);//use_count++
cout << "s_p1引用计数:" << s_p1.use_count() << endl;
std::shared_ptr<int> s_p2 = s_p1;//use_count++
cout << "s_p1引用计数:" << s_p1.use_count() << endl;
{
	std::shared_ptr<int> s_p3(s_p2);//use_count++
	cout << "s_p1引用计数:" << s_p1.use_count() << endl;
}//超出作用域,s_p3被释放,use_count--
cout << "s_p1引用计数:" << s_p1.use_count() << endl;
{
	std::shared_ptr<int> s_p4(std::move(s_p2));//s_p4引用s_p2指向内存,s_p2释放为空,use_count不变
	cout << "s_p1引用计数:" << s_p1.use_count() << endl;
}//超出作用域,s_p4被释放,use_count--
cout << "s_p1引用计数:" << s_p1.use_count() << endl;

输出结果

s_p1引用计数:1
s_p1引用计数:2
s_p1引用计数:3
s_p1引用计数:2
s_p1引用计数:2
s_p1引用计数:1

weak_ptr指针使用

使用 shared_ptr 时, 如果存在循环引用, 将导致内存泄露.weak_ptr指针 是为配合 shared_ptr 而引入的一种智能指针来协助 shared_ptr 工作, 它只可以从一个 shared_ptr 或另一个 weak_ptr 对象构造, 它的构造和析构不会引起引用记数的增加或减少.

weak_ptr 为弱引用, 可以避免此问题, weak_ptr 在功能上类似于普通指针, 然而一个比较大的区别是, 弱引用能检测到所管理的对象是否已经被释放, 从而避免访问非法内存。
注意: 虽然通过弱引用指针可以有效的解除循环引用, 但这种方式必须在程序员能预见会出现循环引用的情况下才能使用, 也可以是说这个仅仅是一种编译期的解决方案, 如果程序在运行过程中出现了循环引用, 还是会造成内存泄漏.

创建weak_ptr指针

std::shared_ptr<int> s_p(new int(10));
std::weak_ptr<int> w_p(s_p);//赋值方式1 s_p.use_count不变
cout << s_p.use_count()<<"   "<<*(w_p.lock()) << endl;
w_p = s_p;//赋值方式2
cout << s_p.use_count() << "   " << *(w_p.lock()) << endl;

输出结果

2   10
2   10

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值