5

考虑以下代码:

struct Calc
{
   Calc(const Arg1 & arg1, const Arg2 & arg2, /* */ const ArgN & argn) :
      arg1(arg1), arg2(arg2), /* */ argn(argn), 
      coef1(get_coef1()), coef2(get_coef2()) 
   {
   }

   int Calc1();
   int Calc2();
   int Calc3();

private:
  const Arg1 & arg1;
  const Arg2 & arg2;
  // ...
  const ArgN & argn;

  const int coef1; // I want to use const because 
  const int coef2; //      no modification is needed.

  int get_coef1() const {
     // calc coef1 using arg1, arg2, ..., argn;
     // undefined behavior?     
  }
  int get_coef2() const {
     // calc coef2 using arg1, arg2, ..., argn and coef1;
     // undefined behavior?
  }

};

struct Calc我打电话时没有完全定义,get_coef1这个get_coef2 代码有效吗?我可以得到UB吗?

4

3 回答 3

8

12.6.2.8:可以为正在构建的对象调用成员函数(包括虚拟成员函数,10.3)。类似地,正在构建的对象可以是 typeid 运算符 (5.2.8) 或 dynamic_cast (5.2.7) 的操作数。但是,如果在基类的所有 mem-initializer 完成之前,在 ctor-initializer 中(或在从 ctor-initializer 直接或间接调用的函数中)执行这些操作,则操作的结果是未定义的。

所以你可以用这种方式初始化你的类成员,但不能初始化基类。而且,正如其他人指出的那样,如果您的函数使用它们的某些值,您应该注意成员初始化顺序。

于 2010-03-22T13:10:15.100 回答
3

由于您的计算所依赖的变量在调用时已经初始化,因此它不应该是未定义的行为。有关相关信息,请参阅问题。

于 2010-03-22T13:00:22.250 回答
0

不是它不是未定义的,但您必须绝对确定这些成员函数仅使用初始化值。还要注意,值是按照它们在类中出现的顺序进行初始化的,而 不是按照它们在初始化列表中出现的顺序。例如:

struct Foo
{
  int a, b;
  int c;
  Foo(): c(1), a(1), b(1) {}
};

在该构造函数中,变量按a、b、c的顺序初始化,列表中的顺序没有任何意义。因此,如果您希望a使用一些计算来初始化的值bc那么您需要将 的 声明移动到 和 之后的一个a点。bc

于 2010-03-22T13:06:25.147 回答