C++中如何将std::shared_ptr<A>的生命周期绑定到std::shared_ptr<B>
解决结构体B引用与A生命周期绑定的问题
方案一:利用自定义删除器绑定A的生命周期
直接创建shared_ptr<B>时,让其删除器持有shared_ptr<A>的拷贝,确保只要shared_ptr<B>存活,A就不会被销毁:
#include <memory> struct A { int i; A(int i):i(i){} }; struct B { A & a; B(A & pA):a(pA){} }; int main() { // 创建A的shared_ptr std::shared_ptr<A> a_ptr = std::make_shared<A>(42); // 构造shared_ptr<B>,删除器捕获a_ptr以维持A的生命周期 std::shared_ptr<B> b_ptr( new B(*a_ptr), [a_ptr](B* b) { delete b; // 当删除器销毁时,a_ptr的拷贝被释放,若这是最后一个持有A的引用,A会被销毁 } ); // 此时可以安全使用b_ptr,无需单独维护a_ptr return 0; }
方案二:用包装结构体统一管理A和B
通过自定义包装结构体,将A的shared_ptr和B的实例放在一起,利用shared_ptr的控制块同时管理两者的生命周期:
#include <memory> struct A { int i; A(int i):i(i){} }; struct B { A & a; B(A & pA):a(pA){} }; // 包装结构体,同时持有A的shared_ptr和B的实例 struct BWrapper { std::shared_ptr<A> a_ptr; B b; // 构造函数初始化A和B BWrapper(std::shared_ptr<A> a) : a_ptr(std::move(a)), b(*a_ptr) {} }; int main() { // 创建包装结构体的shared_ptr,自动绑定A和B的生命周期 auto wrapper = std::make_shared<BWrapper>(std::make_shared<A>(123)); // 若需要单独的shared_ptr<B>,可以通过shared_ptr的别名构造获取 std::shared_ptr<B> b_ptr(wrapper, &wrapper->b); // 使用b_ptr时,A和B的生命周期完全绑定 return 0; }
原理说明
- 方案一通过删除器捕获
shared_ptr<A>,让shared_ptr<B>的生命周期与A绑定:只要b_ptr存在,删除器就存在,a_ptr的拷贝就会维持A的引用计数,避免A被提前销毁。 - 方案二通过包装结构体将A和B纳入同一个
shared_ptr的管理范围,A的生命周期由包装结构体的shared_ptr维持,B的实例与A自然绑定,无需额外处理。
内容的提问来源于stack exchange,提问作者bradgonesurfing
相关产品推荐
相关产品推荐

