为什么要按照声明的顺序初始化成员变量?

新手上路,请多包涵

我今天写了一些代码,得到了一个奇怪的编译错误,这似乎是由于初始化成员变量的顺序与声明的顺序不同造成的。

例子:

 class Test {
    int a;
    int b;

public:
    Test() : b(1), a(2) {
    }
};

int main() {
    Test test;
    return 0;
}

然后,如果我用 -Werror -Wall 编译它:

 $ g++ -Werror -Wall test.cpp
test.cpp: In constructor ‘Test::Test()’:
test.cpp:3:9: error: ‘Test::b’ will be initialized after [-Werror=reorder]
test.cpp:2:9: error:   ‘int Test::a’ [-Werror=reorder]
test.cpp:6:5: error:   when initialized here [-Werror=reorder]
cc1plus: all warnings being treated as errors

我意识到 -Wall 明确要求 GCC 过分警告,但我认为所有这些都是有原因的。那么,初始化成员变量的顺序有什么关系呢?

原文由 Brendan Long 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 638
2 个回答

原因是因为它们是按照它们在您的类中声明的顺序进行初始化的,而不是您在构造函数中初始化它们的顺序,并且它警告您不会使用构造函数的顺序。

这是为了帮助防止 b 的初始化依赖于 a 或反之亦然的错误。

这种排序的原因是因为只有一个析构函数,它必须选择一个“相反的顺序”来销毁类成员。在这种情况下,最简单的解决方案是使用类中的声明顺序来确保始终以正确的相反顺序销毁属性。

原文由 Mark B 发布,翻译遵循 CC BY-SA 3.0 许可协议

您不应该这样做,因为它会降低可读性并且可能具有误导性。

如果你这样做了:

 Test() : b(1), a(b) {}

it would appear that b then a were both set to 1 , whereas actually the uninitialized value of b is used to initialize ab 被初始化为 1 之前。

原文由 CB Bailey 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题