C++ 用模板方法重写虚拟方法

C++ 用模板方法重写虚拟方法,c++,templates,inheritance,virtual-functions,C++,Templates,Inheritance,Virtual Functions,可能重复: 在基类中,函数my_func被定义为虚拟函数。但是,在派生类中,我希望将my_func作为模板方法。这可能吗 看来不是。我得到了错误“无法分配抽象类型的对象”,我认为这与编译器没有确认基类中虚拟my_func的重写有关。这是否显示了一个糟糕的设计 非常感谢 更新: 谢谢你的回答。你们中的一些人建议我发布一些代码,就在这里。 在基类中: virtual void Fill(EventInfo* info, EasyChain* tree, vector<Muon*>&am

可能重复:

在基类中,函数
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;
virtualvoid Fill(EventInfo*info,EasyChain*tree,vector&muon,vector&electronics,vector&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){
模板
空洞填充(EventInfo*info、EasyChain*tree、向量和μ介子、向量和电子、向量和喷射、洛伦兹和大都会){
从您的回答中,我了解到问题的解决方案是在派生类中定义另一个函数:

void Fill(EventInfo* info, EasyChain* tree, vector<Muon*>& muons, vector<Electron*>& electrons, vector<Jet*>& jets, LorentzM& met){
//
}
void Fill(EventInfo*info、EasyChain*tree、向量与μ子、向量与电子、向量与喷流、洛伦兹与梅特){
//
}
但是,对于
\u Jet
Jet*
的情况,此函数和模板函数是相同的,这不是一个问题吗


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

派生类中的函数需要具有相同的签名,以便正确重写基类的函数(并消除抽象类型错误)。 这意味着:

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

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

问题是模板正在更改函数的签名,因此它不再覆盖基类中的虚函数,因此您可以继续使用类它被认为是抽象的


对虚拟函数进行模板化似乎会破坏基类中虚拟函数的多态性。

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

您的模板化方法重载了原始模板(名称相同但参数不同)。为了使派生类非抽象,您还必须重写原始类。您可以同时执行这两个操作,因此在派生类中有两个版本的方法,只需小心并注意调用哪一个版本即可

然后,您可以使重写的重载版本的方法调用新的模板重载版本。这可能会或可能不会实现您想要实现的目标,取决于您想要实现的目标


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

不,你不能直接这样做。为什么不给我们看一些代码,说明你希望通过模板覆盖实现什么?
模板
方法不能是
虚拟的
,所以它永远不能覆盖任何
虚拟的
方法。@NPE,我现在添加了一些代码。只是说,你似乎是在C++中,我强烈建议你使用<代码>超越> /COD>关键字,如果我说得好,C++ 11中存在。SKP,我不能在C++以外的任何东西上编码。谢谢你的答案,但是我怎么知道哪个是被调用的?我是说,如果你看我添加的代码,现在模板和非模板函数如果是je*,模板是相同的。如果在程序中,我用Java*调用函数,哪个调用?谢谢。最具体的方法是调用。但是,我实际上想不出一种方法来使用重写的基类方法中的相同参数调用模板版本…您可能必须在那里添加具有不同名称的私有/受保护的帮助器方法,因此您将有3个方法:抽象
Fill()的一个线性重写
,一行模板重载的
Fill()
,受保护的
Fill2()
,具有与模板重载相同的参数,可以从
Fill()
的两个版本调用它。感谢您的回答,我现在添加了一些代码。