Почему метод подкласса не вызывается?
У меня проблема с подклассом и использованием методов.
Я создаю экземпляр класса 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;
}
Ответы
Ответ 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;
}