Когда список инициализации ищется в C++
Я пытаюсь понять, когда на список инициализации ссылаются (участвуют) во время создания экземпляра не статического члена базового класса и класса. Я прочитал эту статью и эту статью, которая суммирует порядок инициализации класса (я суммировал это здесь)
Инициализация происходит в следующем порядке:
Во-первых, и только для конструктора самого производного класса, как описано ниже, виртуальные базовые классы должны быть инициализированы в том порядке, в котором они отображаются при обходе слева направо по глубине направленного ациклического графа базовых классов, где "слева" -to-right "- порядок появления имен базовых классов в списке базовых спецификаторов производного класса.
Затем прямые базовые классы должны быть инициализированы в порядке объявления, как они появляются в списке базовых спецификаторов (независимо от порядка mem-initializer).
Затем нестатические элементы данных должны быть инициализированы в том порядке, в котором они были объявлены в определении класса (опять же, независимо от порядка mem-инициализаторов). Наконец, тело конструктора выполняется.
Наконец, тело конструктора выполняется.
Теперь я понимаю, прочитав выше, что базовые классы создаются сначала, а затем производный класс. Также члены создаются в том порядке, в котором они были объявлены в определении класса, независимо от их положения в порядке списка инициализации.
Это заставляет меня думать, что каждый раз, когда создается базовый класс или переменная-член во время создания экземпляра класса (в порядке, указанном выше), C++ в основном проверяет список инициализации класса, чтобы увидеть, был ли указан какой-либо конкретный параметр или аргумент для этой базы. переменная класса или члена. Если ничего не указано, C++ выполняет вызов конструктора по умолчанию. Правильно ли мое понимание. Пожалуйста, поправьте меня, если я ошибаюсь.
1 ответ
Да, вы правы 1, когда вы не инициализируете базовый класс или нестатический член в списке инициализации членов или вообще не предоставляете список членов инициализации, применяется следующее:
В не делегирующем конструкторе, если данный потенциально сконструированный подобъект не обозначен с помощью mem-initializer-id (включая случай, когда нет mem-initializer-list, потому что конструктор не имеет ctor-initializer), тогда
если объект является нестатическим элементом данных, который имеет инициализатор элемента по умолчанию и либо
класс конструктора является объединением, и никакой другой вариантный член этого объединения не обозначается как mem-initializer-id или
класс конструктора не является объединением, и, если сущность является членом анонимного объединения, никакой другой член этого объединения не будет обозначен mem-initializer-id,
- объект инициализируется из своего инициализатора элемента по умолчанию, как указано в [dcl.init];
в противном случае, если объект является анонимным объединением или вариантом члена ([class.union.anon]), инициализация не выполняется;
в противном случае объект инициализируется по умолчанию.
1: Вы сказали:
... Если ничего не указано, то C++ выполняет вызов конструктора по умолчанию...
Чтобы быть немного педантичным, значение по умолчанию, инициализированное в приведенной выше цитате, не всегда означает, что будет вызываться конструктор по умолчанию, например, в случае не классовых типов, таких как int
чья инициализация по умолчанию зависит от продолжительности хранения.