Конструкторы вызываются в порядке ABase, BBase, BField, AField, Current. При выходе из функции порядок разрушения обратный: ~Current, ~AField, ~BField, ~BBase, ~ABase.
Определение последовательности вызовов конструкторов и деструкторов при множественном наследовании
Конструкторы вызываются в порядке ABase, BBase, BField, AField, Current. При выходе из функции порядок разрушения обратный: ~Current, ~AField, ~BField, ~BBase, ~ABase.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
В функции check_call_order создаётся объект Current, который наследуется от ABase и BBase и содержит два полевых члена — BField и AField. Требуется выяснить, в каком порядке будут вызваны конструкторы при построении объекта Current.
struct ABase {
ABase() { std::cout << "ABase\n"; }
~ABase() { std::cout << "~ABase\n"; }
};
struct BBase {
BBase() { std::cout << "BBase\n"; }
~BBase() { std::cout << "~BBase\n"; }
};
struct AField {
AField() { std::cout << "AField\n"; }
~AField() { std::cout << "~AField\n"; }
};
struct BField {
BField() { std::cout << "BField\n"; }
~BField() { std::cout << "~BField\n"; }
};
struct Current : ABase, BBase {
BField b;
AField a;
Current() { std::cout << "Current\n"; }
~Current() { std::cout << "~Current\n"; }
};
void check_call_order() {
Current current;
}
Ответ
Конструкторы вызываются в порядке ABase, BBase, BField, AField, Current. При выходе из функции порядок разрушения обратный: ~Current, ~AField, ~BField, ~BBase, ~ABase.
Прямые базовые классы строятся в порядке их перечисления в наследовании. Затем строятся поля в порядке объявления внутри класса, а не по алфавиту и не по порядку списка инициализации. Последним выполняется тело конструктора Current.
При разрушении сначала исполняется тело деструктора Current, затем уничтожаются поля и базовые подобъекты в обратном порядке. Виртуальных баз в этом примере нет.