Возможный дубликат:
Член поля, порядок строительства
Если у меня есть класс с двумя членами, как это:
class A
{
int a;
int b;
A() {}
};
Это порядок в котором a
а также b
построены не определено?
Если я использую cl
, тогда независимо от того, в каком порядке я вызываю конструкторы, члены всегда конструируются в том порядке, в котором они объявлены в классе. В этом случае это всегда будет a
затем b
даже если я определю конструктор для A
лайк:
A() : b(), a() {}
Но я предполагаю, что это просто поведение конкретного компилятора.
Нет. Члены построены в том порядке, в котором они объявлены.
Рекомендуется расположить список инициализаторов в том же порядке, но это не обязательно. Это просто сбивает с толку, если вы этого не сделаете, и может привести к трудно обнаруживаемым ошибкам.
Пример:
struct Foo {
int a; int b;
Foo() : b(4), a(b) { } // does not do what you think!
};
Эта конструкция на самом деле неопределенное поведение, потому что вы читаете неинициализированную переменную в инициализаторе a(b)
,
Стандартная ссылка (C ++ 11, 12.6.2 / 10):
— Затем прямые базовые классы инициализируются в порядке объявления по мере их появления в списке базовых спецификаторов (независимо от порядка mem-initializer).
— Затем не статические члены данных инициализируются в том порядке, в котором они были объявлены в определении класса (опять же, независимо от порядка mem-инициализаторов).
Порядок инициализации такой же, как порядок объявления в классе.
Если порядок в списке инициализации конструктора отличается, компиляторы обычно выдают предупреждение. Например для класса:
class A {
public:
A() : b(1), a(b) {}
private
int a;
int b;
};
GCC предупредит, что:
$ g++ -Wall c.cc
c.cc:5: error: expected `:' before ‘int’
c.cc: In constructor ‘A::A()’:
c.cc:6: warning: ‘A::b’ will be initialized after
c.cc:5: warning: ‘int A::a’
c.cc:3: warning: when initialized here
Это потому, что это может легко привести к ошибкам. В приведенном выше примере значение a
будет не указано