简体   繁体   English

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

[英]Reimplement a virtual function from base class in a derived template class

I have a base class which has a virtual function : 我有一个具有虚函数的基类:

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

}

and a derived (template) class of Base : 和Base的派生(模板)类:

DerviedClass.hpp : DerviedClass.hpp:

Template<typename T>
class DerivedClass : public Base, public T {

  ...
  void myFunction();

}

DerivedClass.cpp : DerivedClass.cpp:

template <>
void DerivedClass<ClassA>::myFunction() {
 //Something ClassA is suppose to do
}

This compiles. 这样编译。 But when I try to instanciate a DerivedClass<ClassB> I get the error : 但是当我尝试实例化DerivedClass<ClassB> ,出现错误:

IProject.o:-1: erreur : undefined reference to `DerivedClass<ClassB>::myFunction()'

Why do I have this error? 为什么会出现此错误? Why it does not take Base::myFunction instead of forcing me to implement a generic myFunction in DerivedClass or a specialized function DerivedClass::myFunction ? 为什么不采取Base::myFunction ,而不是强迫我实现一个通用的myFunctionDerivedClass或专门的功能DerivedClass::myFunction

Note : the assert in myFunction is because ClassB is not supposed to call myFunction during runtime . 注:在myFunction的断言是因为ClassB是不应该叫myFunction过程中runtime For exemple if myFunction is getRadius , DerivedClass<Circle>::getRadius() is okay but DerivedClass<Square>::getRadius() should not be called. 例如,如果myFunctiongetRadius ,则可以使用DerivedClass<Circle>::getRadius() ,但DerivedClass<Square>::getRadius()

Note 2 : The other topics I found were not clear about this point 注意2:关于这一点,我发现的其他主题尚不清楚

Why it does not take Base::myFunction instead of forcing me to implement a generic myFunction in DerivedClass or a specialized function DerivedClass::myFunction ? 为什么不采取Base::myFunction ,而不是强迫我实现一个通用的myFunctionDerivedClass或专门的功能DerivedClass::myFunction

You forced that yourself, by the declaration: 您通过声明强迫自己:

void myFunction();

Consider fully specializing the class template, which will generate classes conditionally with or without overriding myFunction , eg: 考虑完全专门化类模板,无论是否覆盖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
}

If there's some common stuff, you can put it in: 如果有一些常见的东西,可以将其放入:

template <typename T>
class DerivedClassCommons : public Base, public T {
    // common stuff
};

and then refactor DerivedClass to use single inheritance of this class template. 然后重构DerivedClass以使用该类模板的单继承。

That's it for your question, but as others were noting, I think you have a bigger, design problem. 就是您的问题,但是正如其他人所指出的,我认为您有一个更大的设计问题。

Another method to fix the compiler error (not the design error) is to move the definition of myFunction to the derived template: 解决编译器错误(不是设计错误)的另一种方法是将myFunction的定义移至派生模板:

class Base {
   virtual void myFunction() = 0;
}

template<typename T>
class DerivedClass : public Base, public T {
   void myFunction() {
      throw "not implemented, go away";
   }
}

and then specialise only the methods you need: 然后只专门化您需要的方法:

template <>
void DerivedClass<ClassA>::myFunction() {
 //Something ClassA is suppose to do
}

The function is already declared for all types. 该函数已经为所有类型声明 Definition might come from anywhere, including other compilation units. 定义可能来自任何地方,包括其他编译单元。 You'll only need the definition when the function is referred - and your virtual function is (implicitly) referred during construction. 仅在引用函数时才需要定义-并且在构造过程中(隐式)引用了虚拟函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM