2017-11-22 30 views
0

関数fooを持つクラスAがあるとします。
クラスAは、すべて関数fooを持つ少数のクラスの親です。
すべての子クラスは、 A::fooの機能を必要とし、追加します。たとえば
すべての子の特定の関数呼び出しでparent関数を呼び出すC++

class A 
    { 
    public: 
     void foo() 
     { 
     print('A'); 
     } 
    }; 

    class B:public A 
    { 
    public: 
     void foo() 
     { 
      print("B"); 
     } 
    }; 
    class C:public A 
    { 
    public: 
     void foo() 
     { 
      print("C"); 
     } 
    }; 
    void main() 
    { 
     B b; 
     C c; 
     c.foo()// now only goes to C::foo(), meaning print C. I want it to to also go into A::foo() meaning print AC 
     b.foo()//now only goes to B::foo(),meaning print B. want it to print AB 
    } 

そして私がfoo関数でclass D : Aを追加したい場合、私は何かを明らかに不足していますならば、それはまたA::foo()、その後D::foo()

申し訳ありませんを行います。

EDIT:自動的な方法があるかどうかは明らかではありませんでした。

EDIT:回避策を見つけました:今、2つの機能が存在することになりますので、

class A 
    { 
    virtual void foo2(){} 
    public: 
     void foo() 
     { 
     print('A'); 
     foo2(); 
     } 

    }; 

    class B:public A 
    { 
     void foo2() 
     { 
      print("B"); 
     } 
    public: 
    }; 
    class C:public A 
    { 
       void foo2() 
     { 
      print("C"); 
     } 
     public: 
    }; 
    void main() 
    { 
     B b; 
     C c; 
     c.foo()// now prints AC 
     b.foo()//now prints AB 
    } 

は冗長なようです。

+0

'D :: fooボディ '{A :: foo(); ' – Peter

+0

これを自動的に行う方法はありませんが、' foo'関数はそれぞれが必要であれば 'A :: foo()'を呼び出すことができます。 –

+0

thx、それは私がちょうどそれを確かめたいと思ったものです。返信のための –

答えて

0

をあなたは回避策を呼んでいるが確立ゾルでありますこの質問への慎重さと、多くの人がそれを回避策と呼ぶ人もいます。

それもそれをカバーする名前があります。非仮想インタフェースパターン。

ハーブサッター: - S.O.からhttp://www.gotw.ca/publications/mill18.htm

一つの例は、おそらくより多くのがあります: - Non-virtual interface design pattern in C#/C++

私は、これは自動的にそれを行うための方法であると主張していると思います。

2つの機能があるため、その冗長性については - よく、2つ前(基本バージョンと派生バージョン)でした。

いくつかの設計では、仮想メソッドfoo2が純粋な仮想(A抽象を作成する)であれば、即座に派生したすべてのクラスにfoo2を実装するよう強制されます。 (BがAから派生する場合、foo2を実装する必要がありますが、BCから派生したCがfoo2を実装する必要がないため、B :: foo2にアクセスできます)

+1

thxごとにこれを行うだけです。 –

+0

唯一の疑問は、仮想関数が呼び出されたときに関連する関数をコンパイルすることを意味するのと同じ方法でコンパイルするか、関数内で関数としてコンパイルするかということです –

3

A::foo()を使用して、親クラスの関数の実装を呼び出すことができます。あなたが関数をオーバーライドするつもりたび、あなたはvirtualとしてそれを宣言する必要があり、サイドノートとして

class B:public A 
{ 
public: 
    void foo() 
    { 
     A::foo(); 
     print("B"); 
    } 
}; 

:あなたのケースで は、単にその関数呼び出しを追加すると、あなたが望む結果を達成する

class A 
{ 
public: 
    virtual void foo() 
    { 
    print('A'); 
    } 
}; 

そして、それをオーバーライドするとき、overrideキーワードを使用します。

class B:public A 
{ 
public: 
    void foo() override 
    { 
     print("B"); 
    } 
}; 
+0

thx!編集:しかし、私のポイントを逃した。私はAを継承するすべてのクラスでこれを行う必要があります。私の質問は、すべての派生クラスに対してそれを設定する方法です。 –

+0

自動的に行う方法はありません。回答のために派生クラス –