2017-01-12 4 views
0

У меня есть следующая иерархия классов.Не определено Виртуальный метод в производном классе, а также

class A { 
public: 
virtual bool foo() const; 
}; 

class B : public A { 
    // Redeclare foo as virtual here? 
}; 

class C : public B { 
bool foo() const {/*Definition*/ return true;} 
}; 

class D : public B { 
bool foo() const {/*Definition*/ return false;} 
}; 

Так что метод foo(), который класс C и D хочет реализовать, B не делает. Как я могу это достичь? Должен ли я повторно объявлять foo() как виртуальный в классе B?

Примечание: игнорируйте незначительную синтаксическую ошибку здесь и там. Это не настоящий код. Мой вопрос касается только концепции.

+0

Вы забыли точки с запятой после объявлений классов в своем фактическом коде? Это вызовет проблемы. – synchronizer

+0

игнорировать синтаксические ошибки. это не фактический код. Мой вопрос о концепции. – Rajat

ответ

0

Ответ нет, B не нужно повторно реализовывать foo(). Он унаследовал функцию от A. Обратите внимание, что если вы создаете экземпляр B, выделенный в стеке, и вызываете его foo(), то функция не рассматривается как виртуальная - вызывается A foo(). Чтобы использовать переопределенный виртуальный элемент функции в производном классе (используйте преимущества полиморфизма), вы должны вызвать функцию через указатель или ссылку на экземпляр производного класса. В противном случае будет использоваться статический тип объекта.

B b; 

B.foo(); // calls A's foo() 

B* b_ptr = &b; 
b_ptr->foo(); // calls B's foo() 

B& b_ref = b; 
b_ref.foo(); // calls B's foo() 
1
  • Если вы хотите строго производный класс для реализации функции затем сделать функцию pure virtual function в базовом классе.

  • Если вам просто нужен случайный производный класс для повторного использования функции, просто сделайте функцию virtual в базовом классе, что вы сделали в вашем примере.

Теперь, поскольку функция foo в базе class Avirtual поэтому виртуальная таблица vtable будет создавать для class A и все классы, полученные прямо или косвенно из class A.

Запись виртуальной функции хранится в vtable, и они просто заменяются в vtable, если они переопределены в последующих производных классах.

  • Так что, если class B переопределяет foo затем в vtable из class B запись будет B::foo.
  • Итак, если class C переделает foo, то в vtable из class C запись будет C::foo.

Так, class B не требуется объявлять функцию foo в virtual.

Если функция virtual, то разрешение будет выполняться во время выполнения с использованием vtable соответствующего класса, объект которого используется.

+0

Спасибо. Он решил проблему. – Rajat

Смежные вопросы