последовательность инициализации члена класса c++
Я знаю, что в class
члены инициализируются в том порядке, в котором они перечислены. Применимо ли это к группировке переменных в public
и private
и т. д.? Моя путаница заключается в том, что я не мог понять, есть ли предпочтения, такие как private
члены инициализируются в порядке, в котором они были перечислены раньше public
члены, независимо от того, где частные переменные, перечисленные по отношению к публичным в объявлении класса (я знаю, что такое смещение существует по отношению к членам базового класса)
2 ответа:
Правила инициализации класса прописаны в [class.база.init] / 11
В недегатирующем конструкторе инициализация выполняется в следующем порядке:
Во-первых, и только для конструктора самого производного класса (1.8), виртуальные базовые классы инициализируются в том порядке, в котором они появляются на глубине-первый слева направо обход направленного ациклического графа базовых классов, где "слева направо" - порядок появления базовых классов в производный класс базовый-спецификатор-список.
Затем прямые базовые классы инициализируются в порядке объявления, как они появляются в списке базовых спецификаторов (независимо от порядка инициализаторов mem).
Затем нестатические члены данных инициализируются в том порядке, в котором они были объявлены в определении класса (опять же, независимо от порядка инициализаторов mem).
8 Наконец, составной оператор тела конструктора является выполненный.
[Примечание: порядок объявления должен обеспечивать уничтожение базовых и членских подобъектов в обратном порядке инициализации. - Конечная нота]
акцент мой
Таким образом, когда мы смотрим на пулю 3, она конкретно утверждает, что члены построены в том порядке, в котором они появляются в определении. Это означает, что независимо отprivate
,public
, или как они перечислены в списке инициализации членов класса они будут построены в списке инициализации членов класса. порядке, в котором они были объявлены.
Нестатические элементы данных инициализируются в том порядке, в котором они были объявлены.
Компилируя следующий код, вы можете проверить это, если у вас включены предупреждения:
// Example program #include <iostream> #include <string> class Test { private: int a; public: int b; Test() : a(0), b(0) {} }; class TestPrivatePriority { public: int b; TestPrivatePriority() : a(0), b(0) {} private: int a; }; class TestPublicPriority { private: int a; public: int b; TestPublicPriority() : b(0), a(0) {} }; int main() { Test t; TestPrivatePriority t1; TestPublicPriority t2; return 0; }
Это приведет к следующим самоочевидным предупреждениям:
In constructor 'TestPrivatePriority::TestPrivatePriority()': 25:9: warning: 'TestPrivatePriority::a' will be initialized after [-Wreorder] 20:9: warning: 'int TestPrivatePriority::b' [-Wreorder] 22:5: warning: when initialized here [-Wreorder] In constructor 'TestPublicPriority::TestPublicPriority()': 35:9: warning: 'TestPublicPriority::b' will be initialized after [-Wreorder] 32:9: warning: 'int TestPublicPriority::a' [-Wreorder] 37:5: warning: when initialized here [-Wreorder]