当涉及智能指针时,类成员的C++顺序很重要



考虑这个片段:

struct A
{
A(std::unique_ptr<int> somePtr_)
: somePtr{std::move(somePtr_)},
someInt{*somePtr}
{};

std::unique_ptr<int> somePtr;
const int& someInt;
};

这里,传递并存储unique_ptr

然后还会存储对基础数据的引用。

A的对象被破坏时,首先someInt超出范围,然后somePtr

IMHO当涉及智能指针时,成员的顺序很重要,不是吗?

但这种设计不是有些脆弱吗?

如果有人更改了会员顺序怎么办?

有没有一个更好/规范的设计,不需要依赖成员顺序,或者它就像RAII一样?

成员的顺序总是很重要的。

智能指针的出现是一种红色的呼啸。示例中的关键在于,一个成员的初始化取决于其他已经初始化的成员。

成员按照它们在类定义中出现的顺序进行初始化。总是

即使在成员初始值设定项列表中以不同的顺序列出它们,它们仍然按照它们在类定义中出现的顺序进行初始化。当顺序不同时,编译器通常会发出警告。

你会遇到类似的问题:

struct foo {
int x;
int y;
foo() : x(1),y(this->x * 2) {}
};

更改xy的顺序将导致初始化未定义(y将使用未初始化的x(。

但是这个设计不是有些脆弱吗?

是的。当成员的初始化相互依赖时,您需要格外小心。

如果有人更改了会员顺序怎么办?

您将收到编译器警告,最好不要忽略。

是否有更好的/规范的设计,不需要依赖成员顺序,或者就像RAII一样?

您可能不需要引用和智能指针。除掉其中一个。因为他们都是public,所以把他们都拥有真的没有意义。

一般来说,评论中的建议可能是一个解决方案。若重构一个成员成为基类的成员,那个么初始化的顺序是毋庸置疑的,因为基类是首先初始化的。

相关内容

  • 没有找到相关文章

最新更新