我有一个具有虚函数的基类:
class Base {
...
virtual void myFunction() { assert(0 && "not implemented yet"); }
}
和Base的派生(模板)类:
DerviedClass.hpp:
Template<typename T>
class DerivedClass : public Base, public T {
...
void myFunction();
}
DerivedClass.cpp:
template <>
void DerivedClass<ClassA>::myFunction() {
//Something ClassA is suppose to do
}
这个编译。但是当我尝试实现DerivedClass<ClassB>
时,我得到了错误:
IProject.o:-1: erreur : undefined reference to `DerivedClass<ClassB>::myFunction()'
为什么会出现此错误?为什么不采用Base::myFunction
而不是强迫我在myFunction
或专门的函数DerivedClass
中实施通用DerivedClass::myFunction
?
注意: myFunction中的断言是因为ClassB
在myFunction
期间不应该调用runtime
。例如myFunction
为getRadius
,DerivedClass<Circle>::getRadius()
没问题,但不应调用DerivedClass<Square>::getRadius()
。
注2:我发现的其他主题并不清楚这一点
答案 0 :(得分:2)
为什么不采用
Base::myFunction
而不是强迫我在myFunction
或专门的函数DerivedClass
中实施通用DerivedClass::myFunction
?
你通过宣言强迫自己:
void myFunction();
考虑完全专门化类模板,它将在有或没有覆盖myFunction
的情况下有条件地生成类,例如:
template <typename T>
class DerivedClass : public Base, public T {
// not overriding
};
template <>
class DerivedClass<ClassA> : public Base, public ClassA {
void myFunction() override;
};
template <>
void DerivedClass<ClassA>::myFunction() {
// something ClassA is supposed to do
}
如果有一些常见的东西,你可以把它放在:
template <typename T>
class DerivedClassCommons : public Base, public T {
// common stuff
};
然后重构DerivedClass
以使用此类模板的单继承。
这就是你的问题,但正如其他人所指出的那样,我认为你有一个更大的设计问题。
答案 1 :(得分:2)
修复编译器错误(而不是设计错误)的另一种方法是将myFunction
的定义移动到派生模板:
class Base {
virtual void myFunction() = 0;
}
template<typename T>
class DerivedClass : public Base, public T {
void myFunction() {
throw "not implemented, go away";
}
}
然后只专注你需要的方法:
template <>
void DerivedClass<ClassA>::myFunction() {
//Something ClassA is suppose to do
}
答案 2 :(得分:1)
对于所有类型,该函数已经声明。定义可能来自任何地方,包括其他编译单元。在引用函数时,您只需要定义 - 并且在构造期间(隐式)引用您的虚函数。