Это - неопределенное поведение в случае вызова закрытых функций в списке инициализатора?

Рассмотрите следующий код:

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?

5
задан Alexey Malistov 22 March 2010 в 12:58
поделиться

3 ответа

12.6.2.8: Функции-члены (включая виртуальные функции-члены, 10.3) могут вызываться для строящегося объекта. Точно так же строящийся объект может быть операндом оператора typeid (5.2.8) или dynamic_cast (5.2.7). Однако , если эти операции выполняются в инициализаторе ctor (или в функции, вызываемой прямо или косвенно из инициализатора ctor) до завершения всех инициализаторов mem для базовых классов, результат операции не определен.

Таким образом, вы можете инициализировать члены вашего класса, но не базовые классы. И, как указывали другие, вы должны знать порядок инициализации членов, если ваша функция использует некоторые из их значений.

8
ответ дан 13 December 2019 в 19:24
поделиться

Не это не undefined, но вы должны быть абсолютно уверены, что эти функции-члены используют только инициализированные значения. Также обратите внимание, что значения инициализируются в порядке , в котором они появляются в классе , а не в порядке, в котором они появляются в списке инициализации. Например:

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

В этом конструкторе переменные инициализируются в порядке a, b, затем c , порядок в списке ничего не значит. Поэтому, если вы хотите, чтобы значение a было инициализировано с использованием некоторых вычислений на b и c , вам нужно переместить объявление a до точки после b и c .

0
ответ дан 13 December 2019 в 19:24
поделиться

Поскольку переменные, от которых зависят ваши вычисления, уже инициализированы во время вызова, это не должно быть неопределенным поведением. См. этот вопрос для получения дополнительной информации.

3
ответ дан 13 December 2019 в 19:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: