shared_ptr通过引用计数机制管理对象生命周期,每个shared_ptr共享一个控制块,其中记录强引用计数,当强引用计数为0时自动释放资源;循环引用问题发生在多个对象相互以shared_ptr持有对方,导致引用计数无法归零,内存无法释放,例如父子节点间双向强引用;解决方法是将一方改为使用weak_ptr,weak_ptr不增加强引用计数,仅作为观察者,通过lock()安全访问对象,从而打破循环,确保内存正确释放。

shared_ptr
shared_ptr
shared_ptr
shared_ptr
weak_ptr
每当一个新的
shared_ptr
shared_ptr
shared_ptr
举个简单例子:
std::shared_ptr<int> p1 = std::make_shared<int>(42); std::shared_ptr<int> p2 = p1; // 引用计数变为 2 p1.reset(); // 引用计数减为 1,对象未释放 // p2 仍然有效,直到它也被销毁
引用计数的操作是线程安全的(原子操作),多个线程同时增加或减少引用不会导致数据竞争。
循环引用发生在两个或多个对象通过
shared_ptr
典型场景是父子节点结构中,父节点用
shared_ptr
shared_ptr
struct Node;
struct Node {
std::shared_ptr<Node> parent;
std::shared_ptr<Node> child;
};
auto node1 = std::make_shared<Node>();
auto node2 = std::make_shared<Node>();
node1->child = node2;
node2->parent = node1; // 形成循环引用此时:
node1
node2
当
node1
node2
最标准的解决方案是:把循环中的一方改为使用 weak_ptr
weak_ptr
shared_ptr
lock()
shared_ptr
修改上面的例子:
struct Node {
std::shared_ptr<Node> child;
std::weak_ptr<Node> parent; // 改为 weak_ptr
};
auto node1 = std::make_shared<Node>();
auto node2 = std::make_shared<Node>();
node1->child = node2;
node2->parent = node1; // weak_ptr 不增加引用计数
// 访问父节点时:
if (auto parent = node2->parent.lock()) {
// parent 是临时的 shared_ptr,安全访问
std::cout << "Has parent\n";
} else {
std::cout << "Parent is gone\n";
}这样:
node1
node2
node2
node1
node2
node1
weak_ptr
shared_ptr
weak_ptr
weak_ptr
lock()
shared_ptr
lock()
shared_ptr
shared_ptr
weak_ptr
weak_ptr
expired()
lock()
lock()
基本上就这些。关键点是:shared_ptr 靠引用计数自动管理生命周期,但循环引用会打破这个机制,用 weak_ptr 打破循环是最标准做法。
以上就是shared_ptr引用计数怎样工作 循环引用问题解决方案的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号