Вызов виртуальных функций из конструктора или деструктора в C++ может привести к неожиданным результатам, поскольку полиморфизм в этих контекстах работает иначе. Рассмотрим эти тонкости подробнее.
🚩Поведение виртуальных функций в конструкторах и деструкторах
🟠Конструкторы
Виртуальные функции в конструкторах вызываются в контексте текущего класса, а не в контексте производного класса. Когда конструктор базового класса вызывает виртуальную функцию, будет вызвана версия этой функции из самого базового класса, даже если объект принадлежит производному классу. Это связано с тем, что в момент вызова конструктора объект еще не полностью сконструирован как объект производного класса.
🟠Деструкторы
Виртуальные функции в деструкторах также вызываются в контексте текущего класса. Когда деструктор базового класса вызывает виртуальную функцию, будет вызвана версия этой функции из самого базового класса, поскольку деструкторы вызываются в порядке от производного к базовому, и в момент вызова деструктора базового класса объект уже не является объектом производного класса.
🚩Пример для иллюстрации
#include <iostream>
class Base {
public:
Base() {
std::cout << "Base constructor\n";
// Вызов виртуальной функции из конструктора
this->virtualFunction();
}
virtual ~Base() {
std::cout << "Base destructor\n";
// Вызов виртуальной функции из деструктора
this->virtualFunction();
}
virtual void virtualFunction() {
std::cout << "Base virtualFunction\n";
}
};
class Derived : public Base {
public:
Derived() {
std::cout << "Derived constructor\n";
}
~Derived() override {
std::cout << "Derived destructor\n";
}
void virtualFunction() override {
std::cout << "Derived virtualFunction\n";
}
};
int main() {
Derived d;
return 0;
}
🤔 Вывод программы:
Base constructor
Base virtualFunction
Derived constructor
Derived destructor
Base destructor
Base virtualFunction
Ставь 👍 и забирай 📚 Базу знаний