Sobes.tech
Junior — Middle
129

Erklären Sie die Besonderheiten beim Aufruf einer virtuellen Funktion innerhalb des Konstruktors einer Klasse und welche Folgen dies haben kann.

Unternehmen wurden gefragt
101ХР101ХР

Antwort von AI

sobes.tech KI

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