Я искал переполнение стека, но не нашел ничего, что точно отвечает на мой вопрос. У меня есть класс интерфейса, который содержит только чистые виртуальные функции, которые я хотел бы реализовать классами, производными от этого класса.
У меня есть интерфейс, который я назову BaseInterface, который определяет функции, которые я хотел бы переопределить во всех классах, производных от этого интерфейса. В этом примере, скажем, есть только одна чистая виртуальная функция с именем toImplement. Я создаю класс под названием Base, который наследуется от BaseInterface и добавляет некоторые функциональные возможности унаследованным чистым виртуальным функциям. Base по-прежнему является абстрактным классом, поскольку он не реализует функции BaseInterface.
У меня есть несколько классов, которые являются производными от Base, все они используют общие функции Base, но указывают, что происходит, когда toImplement запускается на их экземплярах. Все эти классы должны быть конкретными и удовлетворять всем требованиям, установленным BaseInterface. Ниже я определяю один из этих классов под названием Производные.
Все это отлично работает, когда BaseInterface и Base не созданы. Код компилируется и отлично работает без определения (1.) или реализации (2.) toImplement в Base.
Однако я бы хотел, чтобы toImplement работал с разными типами. Насколько я понимаю, иметь чистые виртуальные функции в шаблонном классе - это нормально. Я использую шаблон BaseInterface и Base для некоторого типа T. Когда я не определяю toImplement в Base (1. ), Я не могу скомпилировать, поскольку Base не знает, какой toImplement использовать в tryUsingImplemented. Если я сейчас добавлю определение в Base, код будет предварительно компилироваться, но компоновщик не сможет найти реализацию Base :: toImplement. Наконец, если я и определяю, и реализую toImplement в Base (1. и 2.), код компилируется.
Мне это не нравится, потому что у меня есть фиктивная реализация toImplement в Base, и я никогда не хочу, чтобы эта реализация запускалась. Кроме того, поскольку Base реализует toImplement, Derived больше не требуется для его реализации. Это делает BaseInterface бесполезным в моих глазах.
Может ли кто-нибудь просветить меня о том, как принудительно реализовать реализацию toImplement в Derived без необходимости сначала реализовать его в Base, если это вообще возможно ?
template <typename T>
class BaseInterface {
virtual void toImplement(T & t) = 0;
};
template <typename T>
class Base : public BaseInterface<T> {
bool m_useImplemented;
public:
explicit Base(bool useImplemented) : m_usedImplemented(useImplemented) {}
void tryUsingImplemented(T & t) {
if (m_useImplemented)
toImplement(t);
}
protected:
// 1: Defining toImplement pure virtual function in Base
virtual void toImplement(T & t);
};
// 2. Implementing a version of toImplement in Base which does nothing
template <typename T>
inline void Base<T>::toImplement(T & t) {
// do nothing
}
class Derived : public Base<int> {
public:
explicit Derived(bool useImplemented) : Base<int>(useImplemented) {}
protected:
// 3. implementing toImplement in Derived
void toImplement(T & t) {
std::cout << "Doing stuff for Derived" << std::endl;
}
};
Base::toImplement
, сделайте его частной функцией. - person Simple   schedule 10.02.2014