9

重複の可能性:
メンバー関数テンプレートを仮想化できますか?

基本クラスでは、関数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){
//
}

でも、この関数とテンプレート関数は同じである場合も同じですが、_JetそれJet*も問題ではないでしょうか。

ここで設計上の問題を示唆している人もいますが、それは本当だと思います。それでは、これを回避する方法を考えなければなりません。

4

4 に答える 4

5

テンプレート化されたメソッドは、元のメソッドをオーバーロードします(同じ名前ですがパラメーターが異なります)。派生クラスを非抽象にするために、元のクラスもオーバーライドする必要があります。どちらも問題なく実行できるため、派生クラスには2つのバージョンのメソッドがあります。どちらが呼び出されるかを注意して意識してください...

次に、オーバーライドされたオーバーロードバージョンのメソッドを作成して、新しいテンプレートのオーバーロードバージョンを呼び出すことができます。これは、達成したいことによって、達成したいことを実行する場合と実行しない場合があります...

派生クラスタイプのポインタがない限り、とにかく直接呼び出すことはできないため、混乱を避けるために、テンプレートメソッドには別の名前を付ける方がよい場合があります。抽象基本クラスへのポインタがある場合は、仮想メソッドであり、派生クラスメソッドが実際に呼び出される場合でも、そこで定義されたパラメータを使用してメソッドを呼び出す必要があります。

于 2012-12-11T10:47:00.840 に答える
2

問題は、テンプレートが関数のシグネチャを変更しているため、基本クラスの仮想関数をオーバーライドしなくなったことです。したがって、クラスは引き続き抽象的です。

仮想関数のテンプレートは、基本クラスの仮想関数のポリモーフィックな性質を打ち負かすようです。

于 2012-12-11T10:42:31.170 に答える
1

基本クラスの関数を適切にオーバーライドする(そして抽象型エラーを取り除く)には、派生クラスの関数に同じシグニチャーが必要です。つまり:

  • 同名
  • 同じパラメータ番号とタイプ
  • 同じ修飾子(たとえば、定数)
  • 互換性のあるリターンタイプ(技術的には署名iircの一部ではありませんが)

したがって、実際、その場合にテンプレートを使用すると、その種のエラーが発生する可能性があります。最良の方法は、コードサンプルを投稿して、人々があなたの特定のケースについてよりよく理解できるようにすることです。

于 2012-12-11T10:41:45.687 に答える
1

my_funcテンプレートバージョンは基本クラスのものと共変ではないため、これを行うことはできません。ところで、これはあなたがここで抱えている設計上の問題です。

于 2012-12-11T10:45:14.763 に答える