我已经搜索了堆栈溢出但是没有找到能完全回答我的问题的东西。我有一个接口类,它只包含纯虚函数,我希望由派生自这个类的类实现。
我有一个接口,我将调用 BaseInterface ,它定义了我希望在从该接口派生的所有类中重写的函数。在这个例子中,假设只有一个名为 toImplement 的纯虚函数。我创建了一个名为 Base 的类,它继承自 BaseInterface ,并为继承的纯虚函数添加了一些功能。 Base仍然是一个抽象类,因为它没有实现 BaseInterface 中的函数。
我有几个派生自 Base 的类,它们都受益于 Base 的常用功能,但指定运行 toImplement 时会发生什么他们的实例。这些类应该都是具体的,并满足 BaseInterface 设置的所有要求。下面我定义了一个名为 Derived 的类。
当BaseInterface和Base没有模板化时,所有这些都可以正常工作。代码编译并运行正常,无需在 Base 中定义(1.)或实现(2.) toImplement 。
但是我希望 toImplement 能够使用不同的类型。根据我的理解,在模板化的类中使用纯虚函数是很好的。我在某些类型T上模板 BaseInterface 和 Base 。当我没有在 Base 中定义 toImplement 时(1。 ),我无法编译,因为Base不知道在 tryUsingImplemented 中使用哪个 toImplement 。如果我现在将定义添加到 Base ,则代码会预编译,但链接器无法找到Base :: toImplement的实现。最后,如果我在 Base (1.和2.)中定义并实现 toImplement ,代码就会编译。
我不喜欢这个,因为我在Base中有一个 toImplement 的虚拟实现,我从不希望运行这个实现。此外,由于基础实施 toImplement ,因此不再需要派生来实施它。这使得 BaseInterface 在我眼中无用。
可以让我了解如何在派生中强制执行 toImplement ,而不必先在 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;
}
};
答案 0 :(得分:3)
为了将来参考,如果您提供了编译器错误消息,将会很有帮助。
然而,在这种情况下,我知道。您的代码中有两个错误:
toImplement
在BaseInterface
中是私有的。tryUsingImplemented
中的查找不会查找基类。您遇到了lookup in dependent bases问题。要解决此问题,请写下this->toImplement(t)
。答案 1 :(得分:0)
如果您打算从派生类中调用它,则需要在toImplement
中将protected
声明为BaseInterface
。我已从派生类中删除了所有重写方法,并将Derived::toImplement
的参数类型替换为int
,并且编译良好。后者是必要的,因为Derived
不是模板,因此您需要使用传递给Base
的模板参数。
#include <iostream>
template <typename T>
class BaseInterface {
protected:
virtual void toImplement(T & t) = 0;
};
template <typename T>
class Base : public BaseInterface<T> {
bool m_useImplemented;
public:
explicit Base(bool useImplemented) : m_useImplemented(useImplemented) {}
void tryUsingImplemented(T & t) {
if (m_useImplemented)
toImplement(t);
}
};
class Derived : public Base<int> {
public:
explicit Derived(bool useImplemented) : Base<int>(useImplemented) {}
protected:
// 3. implementing toImplement in Derived
void toImplement(int & t) {
std::cout << "Doing stuff for Derived" << std::endl;
}
};