从派生模板类中的基类重新实现虚函数

时间:2016-07-28 12:43:32

标签: c++ templates c++11

我有一个具有虚函数的基类:

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中的断言是因为ClassBmyFunction期间不应该调用runtime。例如myFunctiongetRadiusDerivedClass<Circle>::getRadius()没问题,但不应调用DerivedClass<Square>::getRadius()

注2:我发现的其他主题并不清楚这一点

3 个答案:

答案 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)

对于所有类型,该函数已经声明。定义可能来自任何地方,包括其他编译单元。在引用函数时,您只需要定义 - 并且在构造期间(隐式)引用您的虚函数。