成员初始化列表顺序

Order of member initialization list

经过多次简化我的代码后,我发现以下原因导致了问题。

class B {
public:
    B(const int x)
              :_x(x) {}
    const int _x;
};

class C {
public:
    C(const B& b) 
        : _b(b), _b2(_b._x) {}
    B _b2;       // line 1
    const B& _b; // line 2
};

int main() {
    B b(1);
    C c(b);
}

警告 (clang 8.0.0)

test16.cpp:11:22: warning: reference '_b' is not yet bound to a value when used here [-Wuninitialized]
        : _b(b), _b2(_b._x) {}
                     ^
1 warning generated.

g++-6 编译程序。 运行程序导致段错误。

class的成员初始化是按照成员初始化列表(: _b(b), _b2(_b._x))的顺序还是class中成员的顺序(如B _b2; const B& _b;) ?

成员变量的初始化按照它们在 class 中声明的顺序进行。

http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-order

和:

http://en.cppreference.com/w/cpp/language/initializer_list

3) Then, non-static data members are initialized in order of declaration in the class definition.

您在 member initializer list 中指定的顺序无关紧要,non-static 成员按照 class 定义中声明的顺序进行初始化。

The order of member initializers in the list is irrelevant: the actual order of initialization is as follows:

3) Then, non-static data members are initialized in order of declaration in the class definition.

这意味着_b2总是在_b之前被初始化;当_b用于初始化_b2时,它仍然没有初始化。

顺便说一句:类似的规则适用于直接基 classes 的初始化。

2) Then, direct base classes are initialized in left-to-right order as they appear in this class's base-specifier list