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

Is it stable to use arithmetic in a ctor's initialization list?

本文关键字:是否 ctor 初始化 列表      更新时间:2023-10-16

在隐式赋值期间(没有重载操作符)在类的函数初始化列表中使用这样的东西是稳定的吗?

class C{
   public:
      C(int _var): var(_var), i(var*var) 
        {} 
   private:
      int var;
      int i;
};

我得到了一些不稳定的结果,这是为什么?

可以。

您可能想要摆脱初始化顺序依赖,并写入:

  C(int _var): var(_var), i(_var*_var) 

基本上,通过使i依赖于var,您必须确保在类中var在i之前声明。

同样,您可以在C中初始化在父类中定义(和初始化)的东西,因为父类将在C之前构造。

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

假设乘法不溢出,该代码具有定义的含义。

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

但是如果你在代码中得到不稳定的行为,那么错误就在别处。

是的,这是安全的,但在这种情况下你必须小心。您正在使用var而不是_var,因此您必须确保vari之前构建。这里就是这种情况,因为成员是按照声明的顺序构造的(在本例中是var, i),这可能与它们在初始化列表中出现的顺序不同。

在这个例子中它是有效的。在这种情况下也可以:

C(int _var):  i(var*var), var(_var)

但不在此:

class C{
   public:
      C(int _var): var(_var), i(var*var) 
        {} 
   private:
      int i;
      int var;
};

当然,为了安全起见,你可以直接使用_var:

C(int _var):  var(_var), i(_var*_var)