shared_ptr循环引用导致内存泄漏,通过weak_ptr打破循环。示例中A强引用B,B弱引用A,避免了析构时引用计数无法归零的问题,确保对象正确销毁。

shared_ptr
weak_ptr
weak_ptr
#include <iostream>
#include <memory>
#include <string>
// 前向声明,因为A和B互相引用
class B;
class A {
public:
std::string name;
std::shared_ptr<B> b_ptr; // A强引用B
A(std::string n) : name(n) {
std::cout << "A " << name << " constructor\n";
}
~A() {
std::cout << "A " << name << " destructor\n";
}
void set_b(std::shared_ptr<B> b) {
b_ptr = b;
}
};
class B {
public:
std::string name;
std::weak_ptr<A> a_ptr; // B弱引用A,这是打破循环的关键
B(std::string n) : name(n) {
std::cout << "B " << name << " constructor\n";
}
~B() {
std::cout << "B " << name << " destructor\n";
}
void set_a(std::shared_ptr<A> a) {
a_ptr = a;
}
void check_a_status() {
if (auto shared_a = a_ptr.lock()) { // 尝试提升为shared_ptr
std::cout << "B " << name << " observes A " << shared_a->name << " is still alive.\n";
} else {
std::cout << "B " << name << " observes A is gone.\n";
}
}
};
int main() {
std::cout << "--- 示例开始 ---\n";
{
std::shared_ptr<A> pa = std::make_shared<A>("Object_A");
std::shared_ptr<B> pb = std::make_shared<B>("Object_B");
std::cout << "初始引用计数:pa=" << pa.use_count() << ", pb=" << pb.use_count() << "\n";
// 建立引用关系
pa->set_b(pb); // A强引用B,B的引用计数增加
pb->set_a(pa); // B弱引用A,A的引用计数不变
std::cout << "建立引用后:pa=" << pa.use_count() << ", pb=" << pb.use_count() << "\n";
// 此时,pa的use_count应为1 (main函数持有),pb的use_count应为2 (main函数持有,A对象内部持有)
pb->check_a_status(); // B尝试访问A,此时A应该还活着
} // pa和pb超出作用域,智能指针自动析构
std::cout << "--- 示例结束 ---\n";
// 如果没有循环引用,A和B的析构函数都会被调用
return 0;
}shared_ptr
我们经常会遇到这样的情况:你用
shared_ptr
它的形成其实很简单,就是两个或多个对象,它们之间相互持有对方的
shared_ptr
shared_ptr<B>
shared_ptr<A>
想象一下这个过程: 你创建了一个
shared_ptr<A> pa
shared_ptr<B> pb
pa
pb
pb
pa
pb
pa
pa
pb
现在问题来了,当
pa
pb
shared_ptr
pa
pb
shared_ptr
shared_ptr
立即学习“C++免费学习笔记(深入)”;
这就像两个人手拉着手站在悬崖边,谁也松不开,因为一旦松开,对方就可能掉下去。但实际上,只要有一个人愿意放手,或者至少不是用“死死抓住”的方式握着,这个僵局就能打破。这种“死死抓住”就是
shared_ptr
shared_ptr
weak_ptr
weak_ptr
当我们用
weak_ptr
shared_ptr
weak_ptr<A>
shared_ptr<A>
pa
shared_ptr<A>
pb
shared_ptr<B>
pa
shared_ptr<B>
pb
weak_ptr<A>
weak_ptr
现在,当
pa
pb
pa
pb
pa
等A被销毁后,
pb
weak_ptr<A>
expired()
pa
shared_ptr<B>
b_ptr
看,这样一来,A和B都能被正常销毁了。
weak_ptr
weak_ptr
lock()
shared_ptr
lock()
shared_ptr
shared_ptr
这种机制在父子关系、观察者模式或者缓存管理中非常有用。比如一个父节点拥有子节点,子节点需要知道它的父节点是谁,但子节点不应该拥有父节点,否则就会形成循环。这时,子节点持有父节点的
weak_ptr
weak_ptr
weak_ptr
一个很典型的场景就是观察者模式(Observer Pattern)。在观察者模式中,一个主题(Subject)对象会维护一个观察者(Observer)列表,并在状态改变时通知所有观察者。如果主题持有观察者的
shared_ptr
shared_ptr
weak_ptr
lock()
weak_ptr
另一个常见应用是缓存(Cache)机制。假设你有一个对象缓存,里面存放着一些昂贵的对象。你希望这些对象在没有其他地方使用它们时能够被自动清理,以节省内存。如果缓存直接持有这些对象的
shared_ptr
weak_ptr
shared_ptr
shared_ptr
weak_ptr
weak_ptr
以上就是C++内存管理基础中shared_ptr的循环引用问题解决的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号