智能指针使用场景

1 独占资源管理:使用 std::unique_ptr

不允许多个指针同时管理同一块内存. 需要明确表示独占所有权的场景,如资源管理函数中返回一个独占的资源,或者当你明确知道对象的生命周期应该由某个单一的指针负责时。

std::unique_ptr<int> ptr = std::make_unique<int>(10);

 转移指针所有权:

std::unique_ptr<int> ptr2 = std::move(ptr); // ptr 失去了对内存的控制

 make_:避免使用new分配内存后构造函数抛出异常导致内存泄漏的问题.

2 共享资源管理:使用 std::shared_ptr
   防止循环引用:使用 std::weak_ptr

std::shared_ptr<MyClass> sp1 = std::make_shared<MyClass>();  // 创建并管理资源
std::weak_ptr<MyClass> wp = sp1;  // wp 是对 sp1 管理对象的弱引用

if (std::shared_ptr<MyClass> sp2 = wp.lock()) {  // 尝试获取一个共享所有权
    // 使用 sp2 安全地访问对象
} else {
    // sp1 已被销毁,无法访问对象
}
  1. std::weak_ptr 是对 std::shared_ptr 管理对象的弱引用。它不会增加引用计数,也就是说它不影响资源的生命周期。
  2. std::weak_ptr 主要用于避免 std::shared_ptr 之间的循环引用问题。当你需要访问资源,但不想拥有它的所有权时,使用 std::weak_ptr
  3. 在使用 std::weak_ptr 指向的对象之前,通常需要先调用 lock() 方法(weak_ptr没有提供常用的指针操作无法直接访问资源),将其转换为 std::shared_ptr,以确保对象在访问时仍然存在。
#include <iostream>
#include <memory>
using namespace std;
 
class B; // 前置声明类B
class A
{
public:
	A() { cout << "A()" << endl; }
	~A() { cout << "~A()" << endl; }
	weak_ptr<B> _ptrb; // 指向B对象的弱智能指针。引用对象时,用弱智能指针
};
class B
{
public:
	B() { cout << "B()" << endl; }
	~B() { cout << "~B()" << endl; }
	weak_ptr<A> _ptra; // 指向A对象的弱智能指针。引用对象时,用弱智能指针
};
int main()
{
    // 定义对象时,用强智能指针
	shared_ptr<A> ptra(new A());// ptra指向A对象,A的引用计数为1
	shared_ptr<B> ptrb(new B());// ptrb指向B对象,B的引用计数为1
	// A对象的成员变量_ptrb也指向B对象,B的引用计数为1,因为是弱智能指针,引用计数没有改变
	ptra->_ptrb = ptrb;
	// B对象的成员变量_ptra也指向A对象,A的引用计数为1,因为是弱智能指针,引用计数没有改变
	ptrb->_ptra = ptra;
 
	cout << ptra.use_count() << endl; // 打印结果:1
	cout << ptrb.use_count() << endl; // 打印结果:1
 
	/*
	出main函数作用域,ptra和ptrb两个局部对象析构,分别给A对象和
	B对象的引用计数从1减到0,达到释放A和B的条件,因此new出来的A和B对象
	被析构掉,解决了“强智能指针的交叉引用(循环引用)问题”
	*/
	return 0;
}
 
//代码打印如下:
A()
B()
1
1
~B()
~A()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值