В каком порядке пройдет инициализация членов класса в С++? Сначала будет вызван конструктор класса или сначала будут проиницилазованы члены-класса?
class A {}
class B
{
public:
B() = default;
private:
A a;
static A a0;
int i;
static int i0;
}
Сначала будут инициализированы статические члены класса в порядке их объявления еще до первого создания объекта класса. То есть до вызова конструктора класса.
Что касается не статических членов класса, то будут они инициализированы или нет в контексте вашего примера, зависит от того, как будет создаваться объект класса.
Например, при таком создании объекта
B b1;
члены класса будут инициализированы по умолчанию, что для класса B
означает, например, что член класса i
на самом деле никак не будет инициализирован, так как в определении класса у этого члена отсутствует инициализатор.
Однако при таком объявлении объекта класса B
B b2 = B();
объект класса будет инициализирован по значению, что при наличии конструктора по умолчанию означает инициализацию нулем его скалярных членов класса. Так что в этом случае член класса i
будет инициализирован 0.
Из стандарта C++ 17 (9.3 Initializers)
11 An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.
и
8 To value-initialize an object of type T means: (8.2) — if T is a (possibly cv-qualified) class type without a user-provided or deleted default constructor, then the object is zero-initialized...
Имейте в виду, что при объявлении объекта класса, конструктор вызывается в любом случае, однако тело конструктора получает управление уже после создания членов объекта. Для того, чтобы в теле конструктора иметь дело с уже созданными членами объекта, проинициализированными специальным образом, вы можете использовать список инициализации конструктора.
Например,
struct A
{
A() : i( 10 )
{
std::cout << "i = " << i << '\n';
}
int i;
};
Из стандарта:
Инициализация в неделегирующем конструкторе производится в следующем порядке:
■ (13.1) Сначала, и только для конструктора самого производного класса (1.8), инициализируются виртуальные базовые классы в порядке их появления при обходе направленного ациклического графа в направлении «снизу вверх слева направо», где «слева направо» означает очередность появления базовых классов в списке-спецификаторов-баз производного класса.
■ (13.2) Затем инициализируются непосредственные базовые классы в порядке их упоминания в списке-спецификаторов-баз (независимо от порядка mem-инициализаторов).
■ (13.3) Далее инициализируются нестатические данные-члены, в порядке их объявления в описании класса (опять-таки, независимо от порядка mem-инициализаторов).
■ (13.4) Наконец, выполняется составной-оператор тела конструктора.
Замечание. Инициализация в порядке объявления обязательна, так как гарантирует разрушение подобъектов базовых классов и членов в порядке, обратном порядку их инициализации.
Т.е. в вашем классе B будет вызван конструктор A, потом - член a
; i
был бы проинициализирован после a
(в порядке объявления), если бы вы указали его инициализатор (или в конструкторе, типа B():i(5){...}
, или значение по умолчанию типа int i = 6;
).
Статические члены инициализируются до начала работы с классом, однократно.
"По-моему, так" (с) Пух
Если что не так - надеюсь, гуру в стандарте меня исправят (с использованием правильной терминологии и правильных ссылок на стандарт...)
Если класс инициализируется при помощи конструктора, то инициализацией нестатических членов класса занимается конструктор класса. Поэтому ваш вопрос о том, что произойдет "сначала" не имеет смысла. К тому же ваш класс B
может инициализироваться в обход конструктора - через value-initialization.
Порядок инициализации неинлайновых статических членов класса зависит от точки их определения. Вы не привели определений ваших статических членов вообще, поэтому говорить о порядке их инициализации невозможно. Можно лишь сказать, что эти переменные скорее всего проинициализируются перед первым их использованием (хотя в определенных случаях и с этим могут возникнуть проблемы).
Виртуальный выделенный сервер (VDS) становится отличным выбором
Мне нужно сконвертировать переменную типа long в char arrayКак это организовать?
У меня есть приложение (java, android), которое запускает N фоновых потоков Число потоков задаётся пользователемЗапуск потоков происходит в цикле...
Делаю приложение - мозайка из полигонов
Камрады, приветствуюОсваиваю java core