Порядок оценки списка инициализации конструктора

252

У меня есть конструктор, который принимает некоторые аргументы. Я предполагал, что они были построены в указанном порядке, но в одном случае кажется, что они были построены в обратном порядке, что привело к прерыванию. Когда я изменил аргументы, программа перестала прерываться. Это пример синтаксиса, который я использую. Дело в том, что a_ нужно инициализировать перед b_ в этом случае. Можете ли вы гарантировать порядок строительства?

например

class A
{
  public:
    A(OtherClass o, string x, int y) :
      a_(o), b_(a_, x, y) { }

    OtherClass a_;
    AnotherClass b_;
};
Matt
источник
6
Вы говорите, что спрашиваете об аргументах конструктора, но они оцениваются еще до того, как вы дойдете до конструктора, и они оцениваются в неуказанном, определенном компилятором порядке. Но вы действительно спрашиваете о порядке списков инициализации, поэтому я изменил название вопроса для вас.
Роб Кеннеди

Ответы:

278

Это зависит от порядка объявления переменных-членов в классе. Так a_будет первым, потом b_вторым в вашем примере.

арак
источник
22
Фактически, хорошие компиляторы будут предупреждать, если у вас другой порядок в объявлении по сравнению со списком инициализатора конструктора. Например, см. -WreorderВ gcc.
Грег Хьюгилл
236
Причина, по которой они создаются в порядке объявления членов, а не в порядке в конструкторе, состоит в том, что можно иметь несколько конструкторов, но существует только один деструктор. И деструктор уничтожает участников в порядке резерва строительства.
AProgrammer
3
мы имели в виду ... обратный порядок объявления. Не в «конструкции», деструктор не может заглянуть в конструктор, чтобы знать, не так ли?
Конрад Б
196

Цитировать стандарт, для уточнения:

12.6.2.5

Инициализация происходит в следующем порядке:

...

  • Затем нестатические элементы данных должны быть инициализированы в порядке, в котором они были объявлены в определении класса (опять же, независимо от порядка mem-инициализаторов).

...

GManNickG
источник
18

Стандартная ссылка на это теперь , кажется, 12.6.2 раздел 13.3:

(13.3) - Затем не статические члены данных инициализируются в том порядке, в котором они были объявлены в определении класса (опять же, независимо от порядка mem-инициализаторов).

Адам Гетчелл
источник