Когда список инициализации ищется в C++

Я пытаюсь понять, когда на список инициализации ссылаются (участвуют) во время создания экземпляра не статического члена базового класса и класса. Я прочитал эту статью и эту статью, которая суммирует порядок инициализации класса (я суммировал это здесь)

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

  • Во-первых, и только для конструктора самого производного класса, как описано ниже, виртуальные базовые классы должны быть инициализированы в том порядке, в котором они отображаются при обходе слева направо по глубине направленного ациклического графа базовых классов, где "слева" -to-right "- порядок появления имен базовых классов в списке базовых спецификаторов производного класса.

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

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

  • Наконец, тело конструктора выполняется.

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

Это заставляет меня думать, что каждый раз, когда создается базовый класс или переменная-член во время создания экземпляра класса (в порядке, указанном выше), C++ в основном проверяет список инициализации класса, чтобы увидеть, был ли указан какой-либо конкретный параметр или аргумент для этой базы. переменная класса или члена. Если ничего не указано, C++ выполняет вызов конструктора по умолчанию. Правильно ли мое понимание. Пожалуйста, поправьте меня, если я ошибаюсь.

1 ответ

Решение

Да, вы правы 1, когда вы не инициализируете базовый класс или нестатический член в списке инициализации членов или вообще не предоставляете список членов инициализации, применяется следующее:

class.base.init / 9

В не делегирующем конструкторе, если данный потенциально сконструированный подобъект не обозначен с помощью mem-initializer-id (включая случай, когда нет mem-initializer-list, потому что конструктор не имеет ctor-initializer), тогда

  • если объект является нестатическим элементом данных, который имеет инициализатор элемента по умолчанию и либо

    • класс конструктора является объединением, и никакой другой вариантный член этого объединения не обозначается как mem-initializer-id или

    • класс конструктора не является объединением, и, если сущность является членом анонимного объединения, никакой другой член этого объединения не будет обозначен mem-initializer-id,

    - объект инициализируется из своего инициализатора элемента по умолчанию, как указано в [dcl.init];

  • в противном случае, если объект является анонимным объединением или вариантом члена ([class.union.anon]), инициализация не выполняется;

  • в противном случае объект инициализируется по умолчанию.


1: Вы сказали:

... Если ничего не указано, то C++ выполняет вызов конструктора по умолчанию...

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

Другие вопросы по тегам