You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在初始化列表中初始化共享公共指针的const数据成员?

如何在初始化列表中让Bar的a和b共享同一个shared_ptr而无需额外类成员?

我们有一个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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 21:20:44