【问题标题】:override virtual method with template method [duplicate]用模板方法覆盖虚拟方法[重复]
【发布时间】:2012-11-28 21:36:09
【问题描述】:

可能重复:
Can a member function template be virtual?

在基类中,函数my_func 被定义为虚函数。但是,在派生类中,我希望 my_func 成为模板方法。这可能吗?

好像不是。我收到错误“无法分配抽象类型的对象”,我认为这与编译器不承认基类中虚拟my_func 的覆盖有关。这是否揭示了一个糟糕的设计?

非常感谢。

更新: 感谢您的回答。你们中的一些人建议我应该发布一些代码,所以就在这里。 在基类中:

virtual void Fill(EventInfo* info, EasyChain* tree, vector<Muon*>& muons, vector<Electron*>& electrons, vector<Jet*>& jets, LorentzM& met) = 0;

但在派生类中我想拥有:

template<typename _Jet> 
void Fill(EventInfo* info, EasyChain* tree, vector<Muon*>& muons_in, vector<Electron*>& electrons_in, vector<_Jet>& jets_in, LorentzM& met){

从您的回答中,我了解到问题的解决方案是在派生类中定义另一个函数:

void Fill(EventInfo* info, EasyChain* tree, vector<Muon*>& muons, vector<Electron*>& electrons, vector<Jet*>& jets, LorentzM& met){
//
}

但是,对于_JetJet* 的情况,这个函数和模板函数是相同的,那不是问题吗?

这里有人提出了一个设计问题,我想这是真的,我得考虑如何解决这个问题。

【问题讨论】:

  • 不,您不能直接执行此操作。您为什么不向我们展示一些代码来说明您希望通过模板化覆盖实现什么?
  • template 方法不能是virtual,所以它永远不能覆盖任何virtual 方法。
  • @NPE,我现在添加了一些代码。
  • 只是说,你似乎在使用 C++。在 D 中编码,我强烈建议您使用 override 关键字,如果我说得好的话,它会出现在 C++11 中。这样做只有优点,没有缺点;)
  • @skp,我不能为此编写除 C++ 之外的任何代码。

标签: c++ templates inheritance virtual-functions


【解决方案1】:

您的模板化方法重载原始方法(名称相同但参数不同)。您仍然必须覆盖原始类,以使您的派生类非抽象。两种方法都可以,所以派生类中有两个版本的方法,只是要小心并注意哪一个会被调用...

然后您可以使方法的覆盖重载版本调用新的模板重载版本。这可能会也可能不会做您想要实现的目标,具体取决于您想要实现的目标......

模板方法最好使用不同的名称,以避免混淆,因为无论如何你都不能直接调用它,除非你有派生类类型的指针。如果您有指向抽象基类的指针,则必须使用其中定义的参数调用该方法,即使它是虚拟方法并且实际调用的是派生类方法。

【讨论】:

  • 感谢您的回答,但我怎么知道会调用哪一个呢?我的意思是,如果你看一下我添加的代码,现在如果 typename 是 Jet*,那么模板和非模板函数将是相同的。如果,在程序中,我用 Jet* 调用函数,会调用哪一个?再次感谢。
  • 最具体的一个被调用。但是,我实际上想不出一种方法来从覆盖的基类方法中调用具有相同参数的模板版本...您可能必须在其中添加具有不同名称的私有/受保护的辅助方法,因此您将有 3 个方法: 抽象Fill() 的单行覆盖,Fill() 的单行模板化重载,受保护的Fill2() 具有与模板化重载相同的参数,并且将从@987654324 的两个版本调用that @.
【解决方案2】:

问题是模板正在改变函数的签名,所以它不再覆盖基类中的虚函数,因此你的类仍然是抽象的。

模板化虚函数似乎破坏了基类中虚函数的多态性。

【讨论】:

    【解决方案3】:

    派生类中的函数需要具有相同的签名才能正确覆盖基类的函数(并消除抽象类型错误)。 这意味着:

    • 同名
    • 相同的参数编号和类型
    • 相同的限定符(例如常量)
    • 兼容的返回类型(即使从技术上讲这不是签名 iirc 的一部分)

    确实,在这种情况下使用模板会导致这种错误。最好的办法是发布代码示例,以便人们更好地了解您的具体案例。

    【讨论】:

    • 感谢您的回答,我现在添加了一些代码。
    【解决方案4】:

    您不能这样做,因为my_func 模板版本与基类不协变。这是一个设计问题,顺便说一句。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-15
      • 2020-08-31
      • 2014-03-18
      • 2012-06-19
      • 2011-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多