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


252

У мене є конструктор, який бере деякі аргументи. Я припускав, що вони побудовані в перерахованому порядку, але в одному випадку виявляється, що вони були побудовані в зворотному порядку, що призводить до переривання. Коли я перевернув аргументи, програма перестала робити аборт. Це приклад синтаксису, який я використовую. Справа в тому, що a_ в цьому випадку потрібно ініціалізувати перед b_. Чи можете ви гарантувати порядок будівництва?

напр

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

    OtherClass a_;
    AnotherClass b_;
};

6
Ви кажете, що запитуєте про аргументи конструктора, але вони оцінюються, перш ніж ви коли-небудь досягнете конструктора, і вони оцінюються у визначеному порядку, визначеному компілятором. Але ви насправді запитуєте про порядок ініціалізації списків, тому я змінив назву питання для вас.
Роб Кеннеді

Відповіді:


278

Це залежить від порядку оголошення змінної члена в класі. Так a_буде перший, тоді b_буде другий у вашому прикладі.


22
Насправді, хороші компілятори будуть попереджати, якщо ви маєте інший порядок у декларації порівняно зі списком конструктора ініціалізатора. Наприклад, див. -WreorderУ gcc.
Грег Хьюгілл

236
Причина, через яку вони побудовані в порядку декларування членів, а не в порядку в конструкторі, полягає в тому, що у одного може бути кілька конструкторів, але є лише один деструктор. А деструктор знищує елементи в резервному порядку будівництва.
AProgrammer

3
ми мали на увазі ... зворотний порядок декларування. Не "будівництво", деструктор не може вникнути в конструктор, щоб знати, чи може це?
Конрад Б

196

Для цитування стандарту для уточнення:

12.6.2.5

Ініціалізація проходить у такому порядку:

...

  • Потім нестатичні члени даних ініціалізуються в тому порядку, в якому вони були оголошені у визначенні класу (знову ж таки незалежно від порядку пам’яті ініціалізаторів).

...


18

Зараз стандартним посиланням на цей розділ є 12.6.2 розділу 13.3:

(13.3) - Потім нестатичні члени даних ініціалізуються в тому порядку, який вони були оголошені у визначенні класу (знову ж таки незалежно від порядку пам’яті ініціалізаторів).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.