문제

Consider the following code:

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 is not completely defined when I call get_coef1 and get_coef2 Is this code valid? Can I get UB?

도움이 되었습니까?

해결책

12.6.2.8: Member functions (including virtual member functions, 10.3) can be called for an object under construction. Similarly, an object under construction can be the operand of the typeid operator (5.2.8) or of a dynamic_cast (5.2.7). However, if these operations are performed in a ctor-initializer (or in a function called directly or indirectly from a ctor-initializer) before all the mem-initializers for base classes have completed, the result of the operation is undefined.

So you can initialize your class members this way, but not base classes. And, as others pointed, you should be aware of members initialization order, if your function uses some of their values.

다른 팁

Since the variables your calculation depend on are already initialized at the time of the call, it should not be undefined behavior. See this question for related information.

Not it's not undefined, but you have to be absolutely sure that those member functions are only using initialised values. Note also that values are initialised in the order that they appear in the class not the order they appear in the initialisation list. For example:

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

In that constructor, the variables are initialised in the order a, b, then c, the order in the list means nothing. So if you want the value of a to be initialised using some calculation on b and c then you'll need to move the declaration of a to a point after that of b and c.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top