2016-07-06 6 views
0

CとかCと長い間使ってきましたが、C++に慣れていません。状況は我々が持っているということです。条件に基づいたC++関数のオーバーライド

現在、すべての最後のサブクラスのクラス1からメンバ関数を継承しますが、我々は唯一のサブクラスのいずれかでこの機能の動作を変更する必要があり、場合にのみ

base class template 1 -> base class template 2 -> several relevant subclasses

コード内の他の場所の変数が設定され、それ以外の場合はクラス1で定義されている関数を実行します。if-elseのもう一方の側で関数定義全体をスロットしないでこれを行う方法はありますか?私はSFINAE/enable-ifを見てきましたが、これはタイプベースの決定に使用されています。このような単純な条件ではありません。

私は何かが簡単でないか愚かな場合は教えてください。

template <class Face> class Publisher { 
    virtual void publish(...) { 
    // do stuff 
    } 
} 

template <class NewsType> class NewsPublisher : public Publisher<OnlineFace> { 
    // constructors, destructors... 
} 

class MagazinePublisher : public NewsPublisher<Sports> { 
    void publish(...) { 
    if(that.theOther() == value) { 
     // do different stuff 
    } else { 
     // do whatever would have been done without this override here 
    } 
    } 
} 
+2

でしたあなたは、少なくとも私たちに最小の擬似コードサンプルを与えてください。あなたの散文から実際の状況を得ることは非常に難しいです。 –

+2

'if(condition)return base_class :: foo(args);を試したことがありますか? else/*何か他に*/'? –

+0

@ W.F。私がOPの状態を正しく理解していれば、それを行うために 'if-else'ロジックを使いたくないという疑問があります。 –

答えて

2

をあなたの例に従えば、あなたは、単に明示的に基本クラスの実装を呼び出すことができます。

class MagazinePublisher : public NewsPublisher<Sports> { 
    void publish(...) { 
    if(that.theOther() == value) { 
     // do different stuff 
    } else { 
     // call the base class implementation, as this function would not 
     // have been overridden: 
     NewsPublisher<Sports>::publish(...); 
    // ^^^^^^^^^^^^^^^^^^^^^^^ 
    } 
    } 
} 

まあ、私が思うに実際の基本クラス関数publish()virtualのメンバーとして宣言されています。

また

あなたのサンプルはちょうど擬似コードであると私は本当にそれをテストすることができませんでしたから、あなたはNewsPublisher<T>クラスで使用されるべきpublish()実装を追加する必要があるかもしれません:

template <class NewsType> class NewsPublisher : public Publisher<OnlineFace> { 
public: 
    // constructors, destructors... 
    using Publisher<OnlineFace>::publish(); // <<<<<<<<<<<<< 
} 
+0

ええ、これは私が行っていることです。フルネームスコープの最後のビットは私が苦労していたものでした。どうもありがとうございました! – Bronze

0

本当にこの打撃を与える、インスタンスごとに変更することができるならば、他の機能が必要な場合:

struct Base { 
    bool use_base_fn; 
    void fn(){ 
     if (use_base_fn){ 
      //Do as you please for the base function 
      cout << "Base!"; 
     } else { 
      overridden_fn(); 
     } 
    } 

    protected: 
    virtual overridden_fn(){ 
     //to be overriden in base classes 
     //this function will only be called through instances of structs 
     //where 'use_base_fn' is equal to true 
    } 
}; 

struct Derived : Base { 
    Derived() { 
     use_base_fn = true; 
    } 
    protected: 
    void overridden_fn(){ 
     cout << "Derived!"; 
    } 
} 

をこれは動作しませんいくつかの擬似コードを助けるかもしれない

Baseの静的変数はすべての派生クラスで同じになるため、静的変数を使用します。それは、あなたのクラスデザインについて考えて、この振る舞いが本当に必要かどうか、また、1つのvirtualベースメソッドを使用するだけでは不十分かどうかを検討するのに役立つでしょう。例えば、私がreccommend:

struct Base { 
    virtual void fn(){ 
     //Do as you please for the base function 
     cout << "Base!"; 
    } 
}; 

struct Derived : Base { 
    void fn(){ 
     //function is overridden here 
     cout << "Derived!"; 
    } 
} 

は今、あなたは書くことができます。

Base* b1 = new Derived(); 
Base* b2 = new Base(); 
b1->fn(); //prints "Derived!"; 
b2->fn(); //prints "Base!"; 
+0

まあ、私はまた、テンプレート関数パターンを使って別のレベルのインダイレクションを導入することについて考えましたが、ここでは完全な過剰なものです。 –

関連する問題