如何在初始化列表中初始化共享公共指针的const数据成员?
我们有一个Bar类,包含两个数据成员a和b,分别指向A类型的对象。A类型有一个shared_ptr<int>类型的数据成员i。
当前代码中,为了让Bar的a和b共享同一个指针i,我在Bar里新增了一个共享指针成员_i。但我想知道,有没有办法在初始化列表中初始化a和b时,直接共享同一个中间指针i,而不需要额外添加这个类成员?
#include <memory> using namespace std; struct A { const shared_ptr<int> i; explicit A(const shared_ptr<int> &i): i(i) {} }; struct Bar { const shared_ptr<int> _i; const unique_ptr<A> a; const unique_ptr<A> b; explicit Bar(const int &i): _i(make_shared<int>(i)), a(make_unique<A>(_i)), b(make_unique<A>(_i)) {} };
当然可以做到,这里提供几种不依赖额外类成员的实现方式:
方法一:复用已初始化对象的shared_ptr
利用类成员的声明顺序(而非初始化列表顺序),先初始化a并创建共享指针,再让b直接复用a中的i:
#include <memory> using namespace std; struct A { const shared_ptr<int> i; explicit A(const shared_ptr<int> &i): i(i) {} }; struct Bar { // 注意:a的声明必须在b之前 const unique_ptr<A> a; const unique_ptr<A> b; explicit Bar(const int &val): a(make_unique<A>(make_shared<int>(val))), b(make_unique<A>(a->i)) {} };
方法二:使用私有辅助构造函数(更安全,不依赖成员顺序)
如果不想依赖成员声明顺序,可以新增一个私有构造函数,将共享指针作为参数传入,外部构造函数负责创建这个临时指针:
#include <memory> using namespace std; struct A { const shared_ptr<int> i; explicit A(const shared_ptr<int> &i): i(i) {} }; struct Bar { const unique_ptr<A> a; const unique_ptr<A> b; explicit Bar(const int &val) : Bar(make_shared<int>(val)) {} private: // 私有构造函数接收已创建的共享指针 explicit Bar(const shared_ptr<int>& sp) : a(make_unique<A>(sp)), b(make_unique<A>(sp)) {} };
注意事项
- 方法一中必须保证
a的声明顺序在b之前,否则初始化b时a尚未构造完成,访问a->i会触发未定义行为。 - 方法二的实现更清晰,也避免了对成员顺序的依赖,是更推荐的写法。
内容的提问来源于stack exchange,提问作者Max Wong
相关产品推荐
相关产品推荐

