Подтвердить что ты не робот

Почему метод подкласса не вызывается?

У меня проблема с подклассом и использованием методов.

Я создаю экземпляр класса B и сохраняю его как указатель на A. Но когда я использую указатель для вызова перегруженного метода, вывод "A" не "B". Почему?

Это работает на других языках, что я делаю неправильно?

#include <iostream>
using namespace std;

class A {
public:
    void f() {
        cout << "A";
    }
};

class B : public A {
public:
    void f() {
        cout << "B";
    }
};

int main() {
    A *a = new B();
    a->f();
    return 0;
}
4b9b3361

Ответ 1

f() должен быть объявлен virtual в базовом классе A:

class A {
public:
    virtual void f() {
        cout << "A";
    }
};

Другие языки, с которыми вы уже работали, могут по умолчанию использовать виртуальные методы, но С++ не делает (не платите за то, что вы не используете: виртуальные методы несут косвенность при их вызове, что означает, что они немного медленнее, чем обычно вызовы методов).

Добавив virtual, привязка будет отложена во время выполнения (называемая динамическая привязка), и какой вызов функции f() будет определен тип значения.

Поскольку вы не объявили функцию f() как виртуальную, привязка статична (во время компиляции) и будет использовать тип переменной (но не значение), чтобы определить, какой f() для вызова. Таким образом, в вашем текущем статусе кода a->f(); вызывает класс A f(), потому что A является указателем на класс A.

Ответ 2

Для достижения полиморфного поведения метод базового класса должен быть virtual.

Итак, в class A вам нужно изменить void f() на virtual void f().

Ответ 3

Функция должна быть объявлена ​​ virtual, чтобы ее можно было переопределить:

#include <iostream>
using namespace std;

class A {
public:
    virtual void f() {// Here you must define the virtual.
        cout << "A";
    }
};

class B : public A {
public:
    virtual void f() { //Here the "virtual" is optional, but a good practice
        cout << "B";
    }
};

int main() {
    A *a = new B();
    a->f();
    return 0;
}