构造函数初始化列表中的共享参数

时间:2015-12-11 01:03:39

标签: c++ constructor shared-ptr initializer-list

我有这个课程:

class A
{
public:
    A(std::shared_ptr<SomeClass> p);
private:
    std::shared_ptr<SomeClass> _p;
};

class B
{
public:
    B(std::shared_ptr<SomeClass> p);
private:
    std::shared_ptr<SomeClass> _p;
};

class Foo
{
public:
    Foo();
private:
    A _a;
    B _b;
};

来自AB的构造函数参数共享相同的指针引用shared_ptr。在这种情况下:

  • 初始化Foo的最佳方法是什么?

  • 是否仍然可以在Foo的构造函数中使用初始化列表?

我很困惑,因为因为两个类都需要相同的shared_ptr实例,所以我必须将该指针存储在某个地方,并且我认为初始化列表不可能。

此外,如果初始化发生在构造函数的主体中,则意味着AB都应该有move构造函数,对吗?因为我必须做这样的事情:

Foo::Foo() //: Cannot use initializer list
{
    auto ptr = std::make_shared<SomeClass>(SomeClass());
    _a = A(ptr);
    _b = B(ptr);
}

3 个答案:

答案 0 :(得分:2)

实际上,我想到了一个更好的解决方案。创建shared_ptr,然后委托私有构造函数,该构造函数将使用它构造_a_b。 (感谢Zan Lynx建议使用函数参数作为临时存储。)

class Foo {
public:
    Foo(): Foo(std::make_shared<SomeClass>()) {}
private:
    Foo(std::shared_ptr<SomeClass> ptr): _a(ptr), _b(ptr) {}
    A _a;
    B _b;
};

答案 1 :(得分:1)

您无法在构造函数的主体中初始化成员。当身体开始执行时,成员必须已经初始化。因此,如果您尝试执行此操作,则成员将默认构造,然后您只需分配给它们。 AB没有默认构造函数,因此无法编译。

如果您能承受规模的增加,请shared_ptr成为Foo的成员并使用它。

class Foo {
public:
    Foo(): _ptr(std::make_shared<SomeClass>()), _a(_ptr), _b(_ptr) {}
private:
    std::shared_ptr<SomeClass> _ptr;
    A _a;
    B _b;
};

答案 2 :(得分:1)

鉴于您定义类的方式(即无法访问内部shared_ptr),我认为您的解决方案很好。但请注意,AB将需要默认构造函数。这就是在你进入构造函数体之前初始化它们的方式。

此外,一旦您进入构造函数体,您将执行赋值。因此,AB都需要一个赋值运算符。

另外,我认为将std::shared_ptr作为引用传递给函数(包括构造函数)是一种好习惯。