Ответ
Порядок вызова конструкторов в C++ жёстко фиксирован и происходит снизу вверх — от базовых частей к производным:
- Конструкторы базовых классов. Вызываются в порядке их перечисления в списке наследования (слева направо).
- Конструкторы членов класса (полей). Вызываются в порядке их объявления в определении класса, независимо от порядка в списке инициализации конструктора.
- Тело конструктора самого класса.
Деструкторы вызываются в строго обратном порядке.
Пример с множественным наследованием и полями:
#include <iostream>
#include <string>
class BaseA {
public:
BaseA() { std::cout << "BaseA constructor.n"; }
};
class BaseB {
public:
BaseB() { std::cout << "BaseB constructor.n"; }
};
class MemberX {
public:
MemberX() { std::cout << "MemberX constructor.n"; }
};
class MemberY {
public:
MemberY() { std::cout << "MemberY constructor.n"; }
};
// Наследование: BaseA, затем BaseB
// Объявление полей: MemberX mX, затем MemberY mY
class Derived : public BaseA, public BaseB {
MemberX mX;
MemberY mY;
public:
// Список инициализации не влияет на порядок вызова конструкторов
Derived() : mY(), mX() { // Порядок здесь роли не играет
std::cout << "Derived constructor body.n";
}
};
int main() {
Derived d;
return 0;
}
Вывод программы (порядок вызова):
BaseA constructor. // 1. Базовый класс (первый в списке наследования)
BaseB constructor. // 2. Базовый класс (второй в списке наследования)
MemberX constructor. // 3. Поле (первое в объявлении класса)
MemberY constructor. // 4. Поле (второе в объявлении класса)
Derived constructor body. // 5. Тело конструктора Derived