2012-06-29 5 views
11

Я пытаюсь понять точку здесь, на C++. Если класс A имеет не виртуальный метод, а класс B, который расширяет A, переопределяет этот метод, могу ли я создать экземпляр B и каким-то образом использовать метод, определенный в B? Есть ли смысл переопределить не виртуальный метод?Могу ли я использовать метод, переопределяющий не виртуальный метод?

+1

То, что вы называете, называется * скрывается *, а не переопределяет. Взгляните сюда, например: http://stackoverflow.com/questions/2161462/c-inheritance-and-function-overriding – jrok

ответ

31

Есть ли смысл переопределить не виртуальный метод?

Вы на самом деле не отвергая, но это поведение, то есть

B* b = new B(); 
A* a = new B(); 
b->method(); //Calls B's method 
a->method(); // Calls A's method 

Таким образом, указатель/ссылочный тип определяет метод, называемый.

Могу ли я создать экземпляр B и каким-то образом использовать метод, определенный в B?

Да. Тип указателя/ссылки должен иметь тип B. (см. Предыдущий пример).

Если вы не объявляете method быть virtual, вы не можете переопределения, но вы можете скрыть это.

+0

Отличный ответ, спасибо – Eyal

+1

Одна из «полученных» - это ситуация, когда 'A' ​​в свою очередь происходит от некоторого базового класса (или реализует интерфейс), который объявляет' virtual method() ', и в этом случае метод' a->() 'на самом деле вызовет' B.method() '... – BadCash

+0

@Chip Вы пропустили, чтобы подчеркнуть разницу. Этот ответ завершен только с комментарием BadCashs. – ManuelSchneid3r

9

Если B наследует от A и переопределяет метод, определенный в A, то новые экземпляры B позвонит версии B «s. Однако, если метод не является виртуальным, то полиморфное поведение не существует, поэтому, если экземпляр 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 была бы напечатана дважды.

+0

Хорошо написано! :) – niknak

2

Если функция не 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; 
} 
0
  • Нет, не существует никакого механизма, чтобы переопределить невиртуальные метод в классе А.
  • Да, вы можете использовать не виртуальный метод из класса А перегруженный в B с помощью оператора разрешения области видимости A :: имяМетода
Смежные вопросы