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

Reimplement a virtual function from base class in a derived template class

本文关键字:新实现 实现 函数 虚拟 基类 派生      更新时间:2023-10-16

我有一个基类,它有一个虚拟函数:

class Base {
   ...
   virtual void myFunction() { assert(0 && "not implemented yet"); }
}

和衍生的(模板)基类:

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,而不是强迫我在DerivedClass中实现通用myFunction或专用函数DerivedClass::myFunction

注意:myFunction中的断言是因为ClassB不应该在runtime期间调用myFunction。例如,如果myFunctiongetRadius,则DerivedClass<Circle>::getRadius()可以,但不应调用DerivedClass<Square>::getRadius()

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

为什么不使用Base::myFunction,而不是强迫我在DerivedClass中实现通用myFunction或专用函数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
};

然后重构CCD_ 18以使用该类模板的单一继承。

这就是你的问题,但正如其他人所指出的,我认为你有一个更大的设计问题。

修复编译器错误(而不是设计错误)的另一种方法是将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
}

函数已经为所有类型声明了。定义可能来自任何地方,包括其他编译单元。只有当函数被引用时,您才需要定义,而您的虚拟函数在构造过程中(隐式)被引用。