Назад к вопросам
101ХР
Junior — Middle
92
Объясните особенности вызова виртуальной функции внутри конструктора класса и какие последствия это может иметь
Компании, где спрашивали
Ответ от нейросети
sobes.tech AI
В C++ при вызове виртуальной функции внутри конструктора (или деструктора) вызывается версия функции, соответствующая текущему классу, а не производному. Это связано с тем, что во время выполнения конструктора объект считается экземпляром текущего класса, и механизм виртуальных вызовов не учитывает производные классы, так как они ещё не инициализированы.
Последствия:
- Если виртуальная функция переопределена в производном классе, вызов внутри конструктора базового класса не вызовет переопределённую версию, а вызовет базовую.
- Это может привести к неожиданному поведению, если в переопределённой версии функции используется состояние, которое ещё не инициализировано.
Пример:
#include <iostream>
class Base {
public:
Base() {
foo(); // вызов виртуальной функции
}
virtual void foo() {
std::cout << "Base::foo" << std::endl;
}
};
class Derived : public Base {
public:
int* data;
Derived() : data(new int(42)) {}
void foo() override {
std::cout << "Derived::foo, data = " << (data ? *data : 0) << std::endl;
}
};
int main() {
Derived d;
return 0;
}
Вывод будет:
Base::foo
Потому что во время выполнения конструктора Base объект ещё не является Derived, и вызов foo() сработает как Base::foo. Это важно учитывать, чтобы избежать ошибок и непредсказуемого поведения.