последовательность инициализации члена класса c++


Я знаю, что в class члены инициализируются в том порядке, в котором они перечислены. Применимо ли это к группировке переменных в public и private и т. д.? Моя путаница заключается в том, что я не мог понять, есть ли предпочтения, такие как private члены инициализируются в порядке, в котором они были перечислены раньше public члены, независимо от того, где частные переменные, перечисленные по отношению к публичным в объявлении класса (я знаю, что такое смещение существует по отношению к членам базового класса)

2 2

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]