在ctor的初始化列表中使用算术是否稳定?

use*_*369 7 c++ constructor

在隐式赋值期间在类的ctor初始化列表中使用类似的东西是否稳定(没有运算符重载):

class C{
   public:
      C(int _var): var(_var), i(var*var) 
        {} 
   private:
      int var;
      int i;
};
Run Code Online (Sandbox Code Playgroud)

我得到了一些古怪的结果,为什么会这样?

Mor*_*hai 8

是.

您可能希望摆脱初始化顺序依赖关系,并编写:

  C(int _var): var(_var), i(_var*_var) 
Run Code Online (Sandbox Code Playgroud)

基本上,通过使我依赖var,你必须确保在类中的i之前声明var.

类似地,您可以在父类中定义(和初始化)的C中初始化某些内容,因为父类将在C之前构造.

最佳实践要求您了解上述内容,并避免混淆任何内容的情况 - 也许文档我依赖于var,以便下一个程序员(可能是您自己)不会引入初始化顺序问题.


Ste*_*sop 5

该代码定义了含义,假设乘法不会溢出.

请注意,它严重依赖于var之前i在类中定义的事实(初始化列表中的顺序无关紧要,重要的是成员自身的定义顺序).否则i将使用单元化数据成员进行初始化var.

但是,如果您正在使用该代码获得不稳定的行为,那么该错误就在其他地方.


Chr*_*ica 5

是的,这是安全的,但在这种情况下你必须要小心.你正在使用var而不是_var,所以你必须确定var之前是否构建过i.这是这里的情况中,由于构件在其声明的顺序构成(在这种情况下var,i),其可以是从它们在初始化列表中出现的顺序不同.

所以在这种情况下它有效.它也适用于这种情况:

C(int _var):  i(var*var), var(_var)
Run Code Online (Sandbox Code Playgroud)

但不是这个:

class C{
   public:
      C(int _var): var(_var), i(var*var) 
        {} 
   private:
      int i;
      int var;
};
Run Code Online (Sandbox Code Playgroud)

但当然,要始终保持安全,您可以使用_var:

C(int _var):  var(_var), i(_var*_var)
Run Code Online (Sandbox Code Playgroud)