Sobes.tech
Back to questions
Junior — Middle
93

Объясните особенности вызова виртуальной функции внутри конструктора класса и какие последствия это может иметь

Companies where asked
101ХР101ХР

Answer from AI

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. Это важно учитывать, чтобы избежать ошибок и непредсказуемого поведения.