Sobes.tech
Junior — Middle
121

Εξηγήστε τα χαρακτηριστικά της κλήσης μιας εικονικής λειτουργίας μέσα στον κατασκευαστή μιας κλάσης και ποιες μπορεί να είναι οι συνέπειες.

Εταιρείες όπου ρωτήθηκαν
101ХР101ХР

Απάντηση από 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. Это важно учитывать, чтобы избежать ошибок и непредсказуемого поведения.