初始化列表似乎取决于 class 中变量的顺序

Initializer list seems to be dependent on the order of variables in a class

我是 C++ 的新手,这是我的第一个 post。我想了解初始化列表。问题是我越来越糊涂了。我做了一个简单的程序,没有用,但我收到一个我不明白的警告。

#include <iostream>

using namespace std;

class Base{

    private:
        string monkey2 = "";
        string monkey1 = "";
    public:
        Base(string) : monkey2{monkey1}{
            cout << "monkey1 " << monkey1 << endl;
            cout << "monkey2 " << monkey2 << endl;
        }
};

int main()
{
    return 0;
}

我收到的警告是:

field 'monkey' is uninitialized when used here

和一个指向正下方行的箭头 public:

奇怪的是,如果我改变字符串的顺序:

private:
    string monkey2 = "";
    string monkey1 = "";
public:

收件人:

private:
    string monkey1 = "";
    string monkey2 = "";
public:

警告消失了,我不明白为什么。我可以使用 g++ 编译它,但是当我将编辑器 vim 与 YCM 和 Clang 7.0.0 一起使用时,我收到警告。我试图在 g++ 中激活尽可能多的警告,但我无法获得相同的警告。是我的代码还是。还是 Clang?

数据成员按照声明的顺序进行初始化。因此,当你有

class Base {
    public:
        Base();

    private:
        string monkey2 = "";
        string monkey1 = "";
};

变量 monkey2 将在 monkey1 之前 初始化,而不管 ctor Base::Base() 做什么。当数据成员的初始化相互依赖时,这会导致难以发现问题。这里,

Base() : monkey2{monkey1} { /* ... */ }

monkey2monkey1 初始化,但由于声明的顺序,此时 monkey1 未初始化,因为 monkey2 首先被初始化。这就是您收到警告的原因,这也是为什么通过先声明 monkey1 来减轻警告的原因 - 然后,通过 in-class 初始化程序将 monkey1 设置为 ""monkey2 使用已经初始化的 monkey1 初始化。

以下(公认的主观)准则适用于这种情况:

  • 如果可以避免跨数据成员的初始化依赖性,请这样做。
  • 如果您有构造函数初始化列表,请严格遵循声明数据成员的顺序(参见 C.47)。
  • 如果数据成员有一个合理的默认值,可能跨 ctor 重载,使用 in-class 初始化(但是,不要像在 Base::Base(string) 中那样添加另一个初始化指令实施(参见 C.48)。