简体   繁体   English

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

[英]C++ Order of class members when smart pointers are involved matters

Consider this snippet:考虑这个片段:

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

Here, a unique_ptr is passed and stored.在这里,传递并存储了一个unique_ptr

Then a reference to the underlying data is also stored.然后还存储对基础数据的引用。

When an object of A is destroyed, first someInt gets out of scope and then somePtr .A的对象被销毁时,首先someInt超出范围,然后somePtr

IMHO the order of the members matters when smart pointers are involved, isn't it?恕我直言,当涉及智能指针时,成员的顺序很重要,不是吗?

But is this design not somewhat brittle?但是这样的设计是不是有些脆弱?

What if someone changes the member order?如果有人更改会员订单怎么办?

Is there a better/canonical design where there is no need of relying on the member order, or is it just like it is with RAII?是否有更好的/规范的设计,不需要依赖成员订单,或者就像 RAII 一样?

Order of members matters always.成员的顺序总是很重要的。

The presence of the smart pointer is a red hering.智能指针的存在是一个红色的地方。 The crux in your example is just that initialization of one member depends on some other member already being initialized.您示例中的关键只是一个成员的初始化取决于已经初始化的其他成员。

Members are initialized in the order they appear in the class definition.成员按照它们在类定义中出现的顺序进行初始化。 Always.总是。

Even if you list them in different order in the member initializer list, they are still initialized in the order they appear in the class definition.即使您在成员初始值设定项列表中以不同的顺序列出它们,它们仍然按照它们在类定义中出现的顺序进行初始化。 And usually compilers warn when the order is different.通常编译器会在顺序不同时发出警告。

You get similar issue with:您遇到类似的问题:

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

Changing the order of x and y would render the initialization undefined ( y would use uninitialzed x ).更改xy的顺序将使初始化未定义( y将使用未初始化的x )。

But is this design not somewhat brittle?但是这样的设计是不是有些脆弱?

Yes it is.是的。 You need to be extra careful when initialization of members depends on each other.当成员的初始化相互依赖时,您需要格外小心。

What if someone changes the member order?如果有人更改会员订单怎么办?

You will get a compiler warning, that you better not ignore.您将收到编译器警告,最好不要忽略。

Is there a better/canonical design where there is no need of relying on the member order, or is it just like it is with RAII?是否有更好的/规范的设计,不需要依赖成员订单,或者就像 RAII 一样?

You probably do not need a reference and a smart pointer.您可能不需要引用智能指针。 Get rid of one of them.摆脱其中之一。 As they are both public there is really no point in having them both.因为他们都是public所以让他们两个都没有意义。

In general, what was suggested in a comment may be a solution.一般来说,评论中提出的可能是一个解决方案。 If you refactor one member to be member of a base class then there is no doubt about order of initialization, because base classes are initialized first.如果您将一个成员重构为基类的成员,则初始化顺序毫无疑问,因为基类首先被初始化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM