Я пытаюсь понять точку здесь, на С++. Если класс A имеет не виртуальный метод, а класс B, который расширяет A, переопределяет этот метод, могу ли я создать экземпляр B и каким-то образом использовать метод, определенный в B? Есть ли смысл переопределить не виртуальный метод?
Могу ли я использовать метод, переопределяющий не виртуальный метод?
Ответ 1
Есть ли смысл переопределить не виртуальный метод?
Вы на самом деле не переопределяете, но это поведение, т.е.
B* b = new B();
A* a = new B();
b->method(); //Calls B method
a->method(); // Calls A method
Таким образом, тип указателя/ссылки определяет метод.
Могу ли я создать экземпляр B и каким-то образом использовать метод, определенный в B?
Да. Тип указателя/ссылки должен иметь тип B. (см. Предыдущий пример).
Если вы не объявляете method
равным virtual
, вы не можете переопределить, но можете скрыть его.
Ответ 2
Если B
наследует от A
и переопределяет метод, определенный в A
, то новые экземпляры B
будут вызывать B
версию. Однако, если метод не является виртуальным, тогда нет никакого полиморфного поведения, поэтому, если на экземпляр B
ссылаются как A
, тогда метод будет A
. Например:
struct A {
void foo () { std::cout << "A::foo" << std::endl; }
};
struct B : public A {
void foo () { std::cout << "B::foo" << std::endl; }
};
B b;
b.foo();
A *a = &b;
a->foo();
Вывод кода выше:
B::foo
A::foo
Однако, если метод foo
был виртуальным, тогда B::foo
был бы напечатан дважды.
Ответ 3
Если функция не является virtual
, тогда тип переменной определяет, какая реализация также отправляется:
#include <iostream>
using namespace std;
struct A {
void f() { cout << "A" << endl; }
};
struct B : public A {
void f() { cout << "B" << endl; }
};
int main(int args, char** argv) {
B b;
A& a = b;
b.f();
a.f();
return 0;
}
Ответ 4
- Нет, нет механизма для переопределения не виртуального метода в классе А.
- Да, вы можете использовать не виртуальный метод из класса A, перегруженного в B, с помощью оператора разрешения области A:: methodName