Должен ли я объявить f () явно в B?
Да , вы должны объявить в классе ' определение все виртуальные функции любых базовых классов, которые вы хотите переопределить в классе. Что касается того, почему: Это так синтаксис C ++.
Обратите внимание, что ключевое слово virtual
может быть опущено для объявления переопределяющих виртуальных функций:
class base {
virtual void f();
virtual void g();
};
class derived : public base {
virtual void f(); // overrides base::f()
void g(); // overrides base::g()
};
Примечание: объявление класса таково: class my_class;
, тогда как это class my_class { /* ... */ };
является определением класса . Есть ограниченное количество вещей, которые вы можете сделать с классом, который был объявлен , но не определен . В частности, вы не можете создавать его экземпляры или вызывать функции-члены.
Подробнее о различиях между декларацией и определениями см. здесь .
Хорошо, в интересах обсуждения «декларация против определения», происходящего в комментариях, приведу цитату из стандарта C ++ 03, 3.1 / 2:
Объявление является определением, если оно не [...] является объявлением имени класса
[...].
3.1 / 3 затем приводит несколько примеров. Среди них:
[Пример: [...]
struct S { int a; int b; }; // defines S, S::a, and S::b
[...]
struct S; // declares S
- конец примера]
Подводя итог: стандарт C ++ считает struct S;
объявлением, а struct S { /*...*/ };
определением. Я считаю, что это сильная резервная копия моей интерпретации «объявление против определения» для классов в C ++.