Проблема поверхностная заключается в том, что вы вызываете виртуальную функцию, которая еще не известна (объекты создаются от родителя к ребенку, как и таблицы). Ваш компилятор предупреждал вас об этом.
Насколько я понимаю, существенная проблема заключается в том, что вы пытаетесь повторно использовать функциональность путем наследования. Это почти всегда плохая идея. Вопрос дизайна, так сказать:)
По сути, вы пытаетесь создать экземпляр шаблона Template Method, чтобы отделить что от , когда : сначала прочитать некоторые данные (каким-то образом), затем обработать их (каким-то образом ).
Вероятно, это будет намного лучше работать с агрегацией: передайте функцию Processing методу Template, который будет вызван в нужное время. Может быть, вы даже можете сделать то же самое для функции чтения.
Агрегирование может быть выполнено двумя способами:
- Использование виртуальных функций (т. Е. Связывание во время выполнения)
- Использование шаблонов (т. Е. Привязка времени компиляции)
Пример 1: привязка во время выполнения
class Data {};
class IReader { public: virtual Data read() = 0; };
class IProcessor { public: virtual void process( Data& d) = 0; };
class ReadNProcess {
public:
ReadNProcess( IReader& reader, IProcessor processor ){
processor.process( reader.read() );
}
};
Пример 2: привязка времени компиляции
template< typename Reader, typename Writer > // definitely could use concepts here :)
class ReadNProcess {
public:
ReadNProcess( Reader& r, Processor& p ) {
p.process( r.read() );
}
};