构造函数初始化列表中的共享参数
Shared argument in constructor 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;
};
来自 A
和 B
的两个构造函数参数共享相同的指针引用 shared_ptr
。在这种情况下:
初始化 Foo
的最佳方式是什么?
是否仍然可以在 Foo
的构造函数中使用初始化列表?
我很困惑,因为两个 类 都需要相同的 shared_ptr
实例,所以我必须将该指针存储在某个地方,我认为初始化列表不可能做到这一点。
此外,如果初始化发生在构造函数的主体中,则意味着 A
和 B
都应该有一个 move
构造函数,对吗?因为我必须做这样的事情:
Foo::Foo() //: Cannot use initializer list
{
auto ptr = std::make_shared<SomeClass>(SomeClass());
_a = A(ptr);
_b = B(ptr);
}
您不能在构造函数的主体中初始化成员。当主体开始执行时,成员必须已经初始化。因此,如果您尝试这样做,成员将被默认构造,然后您将只是分配给他们。 A
和 B
没有默认构造函数,因此无法编译。
如果您负担得起增加尺寸,请将 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;
};
鉴于您定义 类 的方式(即无法访问内部 shared_ptr
),我认为您的解决方案很好。但请注意 A
和 B
将需要默认构造函数。这就是它们在进入构造函数体之前的初始化方式。
此外,一旦进入构造函数体,您将进行赋值。所以 A
和 B
都需要一个赋值运算符。
此外,我觉得将 std::shared_ptr
作为引用传递给函数(包括构造函数)是一种很好的做法。
其实我想到了更好的解决办法。创建 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;
};
我有这个类:
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;
};
来自 A
和 B
的两个构造函数参数共享相同的指针引用 shared_ptr
。在这种情况下:
初始化
Foo
的最佳方式是什么?是否仍然可以在
Foo
的构造函数中使用初始化列表?
我很困惑,因为两个 类 都需要相同的 shared_ptr
实例,所以我必须将该指针存储在某个地方,我认为初始化列表不可能做到这一点。
此外,如果初始化发生在构造函数的主体中,则意味着 A
和 B
都应该有一个 move
构造函数,对吗?因为我必须做这样的事情:
Foo::Foo() //: Cannot use initializer list
{
auto ptr = std::make_shared<SomeClass>(SomeClass());
_a = A(ptr);
_b = B(ptr);
}
您不能在构造函数的主体中初始化成员。当主体开始执行时,成员必须已经初始化。因此,如果您尝试这样做,成员将被默认构造,然后您将只是分配给他们。 A
和 B
没有默认构造函数,因此无法编译。
如果您负担得起增加尺寸,请将 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;
};
鉴于您定义 类 的方式(即无法访问内部 shared_ptr
),我认为您的解决方案很好。但请注意 A
和 B
将需要默认构造函数。这就是它们在进入构造函数体之前的初始化方式。
此外,一旦进入构造函数体,您将进行赋值。所以 A
和 B
都需要一个赋值运算符。
此外,我觉得将 std::shared_ptr
作为引用传递给函数(包括构造函数)是一种很好的做法。
其实我想到了更好的解决办法。创建 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;
};