Могу ли я использовать метод, переопределяющий не виртуальный метод?

Я пытаюсь понять точку здесь, на С++. Если класс 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