Порядок вызова конструкторов

#include <iostream>
using namespace std;
struct A{
A() {cout << "A" << endl;}
A(int a) {cout << "A+" << endl;}
};

struct B : virtual A{
B() : A(1) {cout << "B" << endl;}
};
struct C : virtual A{
C() : A(1) {cout << "C" << endl;}
};
struct D : virtual A{
D() : A() {cout << "D" << endl;}
};
struct E : B, virtual C, D{
E(){cout << "E" << endl;}
};
struct F : D, virtual C{
F(){cout << "F" << endl;}
};
struct G : E, F{
G() {cout << "G" << endl;}
};

int main(){
G g;
return 0;
}

Программа печатает:

A
C
B
D
E
D
F
G

Я хотел бы знать, какие правила я должен использовать, чтобы определить, в каком порядке вызываться конструкторы. Благодарю.

0

Решение

Вы должны следовать правилам, приведенным в стандарте C ++:

[C++11: 12.6.2/10]: В не делегирующем конструкторе инициализация происходит в следующем порядке:

  • Во-первых, и только для конструктора самого производного класса (1.8), виртуальные базовые классы инициализируются в том порядке, в котором они отображаются при обходе слева направо по глубине направленного ациклического графа базовых классов, где «слева-направо» направо »- это порядок появления базовых классов в производном классе базовый спецификатор-лист.
  • Затем прямые базовые классы инициализируются в порядке объявления, как они появляются в списке базовых спецификаторов (независимо от порядка MEM-Инициализаторы).
  • Затем не статические члены данных инициализируются в порядке, в котором они были объявлены в определении класса (опять же, независимо от порядка MEM-Инициализаторы).
  • Наконец, компаунд-заявление тела конструктора выполнен.

[ Заметка: Порядок объявления должен гарантировать, что базовые и членские подобъекты уничтожаются в обратном порядке инициализации. —Конечная записка]

1

Другие решения

Виртуальные базовые подобъекты создаются вначале самым производным классом перед любыми другими базами. Это единственный способ, который имеет смысл, поскольку отношение виртуальных баз к самому производному объекту неизвестно до конструирования объекта, во время выполнения (следовательно, «виртуальное»). Все промежуточные инициализаторы для виртуальных баз игнорируются.

Итак, каковы ваши виртуальные базы? G происходит от E а также F, E происходит практически от Cчто, в свою очередь, вытекает практически из A, так A, C являются первыми. Следующий, F не добавляет никаких дополнительных виртуальных баз. Следующий, E имеет не виртуальные базы B а также Dв том порядке, в котором строятся следующие, а затем E завершено. Потом приходит Fне виртуальная база D, а также F завершено. В заключение, G завершено.

В общем, это виртуальные базы A, Cто не виртуальные базы B, D, E а также D, F, а потом G сам.

1

Вы можете исследовать порядок вызовов конструктора из этой цитаты C ++ Standard и попытаться перехватить его самостоятельно

10 В не делегирующем конструкторе инициализация продолжается в
следующий порядок: — сначала и только для конструктора самого
производный класс (1.8), виртуальные базовые классы инициализируются в порядке
они появляются на глубине первого слева направо обхода направленного
ациклический граф базовых классов, где «слева направо» — это порядок
Появление базовых классов в производном классе
базовый спецификатор-лист. — Затем прямые базовые классы инициализируются в
порядок декларирования в том виде, в котором он указан в списке базовых спецификаторов
(независимо от порядка установки mem-инициализаторов). — Тогда не статично
члены данных инициализируются в том порядке, в котором они были объявлены в
определение класса (опять же, независимо от порядка
MEM-инициализаторы). — Наконец, составное заявление
тело конструктора выполнено. [Примечание: порядок декларации
поручено обеспечить уничтожение базовых и членских подобъектов в
обратный порядок инициализации. —Конечная записка]

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector