C ++の他の抽象クラスから複数継承されている抽象クラスの実装を作成する方法はありますか?

Avi

私には2つの「インターフェース」クラスがあります:AbstractAccessAbstractPrint、およびAbstractRunそれらから継承し、それらのメソッドを使用するクラス。また、インターフェイスの実装は2つあります。AccessorforAbstractAccessとPrintforです。AbstractPrint

#include <iostream>                                                                                                                                                                                                

using namespace std;                                                                                                                                                                                               

class AbstractAccess {                                                                                                                                                                                             
    public:                                                                                                                                                                                                        
    virtual string access (void) = 0;                                                                                                                                                                              
};                                                                                                                                                                                                                 

class AbstractPrint {                                                                                                                                                                                              
    public:                                                                                                                                                                                                        
    virtual void print (string) = 0;                                                                                                                                                                               
};                                                                                                                                                                                                                 

class AbstractRun : virtual public AbstractAccess, virtual public AbstractPrint {                                                                                                                                  
    public:                                                                                                                                                                                                        
        void run (void) {                                                                                                                                                                                          
            print(access());                                                                                                                                                                                       
        }                                                                                                                                                                                                          
};                                                                                                                                                                                                                 

class Accessor : virtual public AbstractAccess {                                                                                                                                                                   
    public:                                                                                                                                                                                                        
        string access (void){                                                                                                                                                                                      
            return name;                                                                                                                                                                                           
        }                                                                                                                                                                                                          

            void setName(string name) {                                                                                                                                                                                
            this->name = name;                                                                                                                                                                                     
        }                                                                                                                                                                                                          

    private:                                                                                                                                                                                                       
        string name;                                                                                                                                                                                               
};                                                                                                                                                                                                                 

class Print: public virtual AbstractPrint {                                                                                                                                                                        
    public:                                                                                                                                                                                                        
        void print (string s) {                                                                                                                                                                                    
            cout << s << endl;                                                                                                                                                                                     
        }                                                                                                                                                                                                          
};                                                                                                                                                                                                                 

インターフェイスをAbstractRun実装にキャストしたり、AbstractRunの「run」メソッドのみを使用して実装されたインターフェイスを使用する実装クラスRunを作成したりする方法はありますか?

ミカエルH

あなたはすでに問題を解決しましたが、私はこれをさらに調査し、継承についての混乱を正したいと思います。

継承は、クラスが別のクラスと「isa」の関係にある場合に使用されます。派生クラスは、継承元のクラスの代わりになるはずです。

あなたの場合、あなたは安全にclass Printaでclass AbstractPrintあり、class Access同様にaclass AbstractPrintある言うことができるので、ここでは継承は問題ありません

一方、class AbstractRunはではなく、でもAbstractPrintありませんAbstractAccessAbstractRun単にハンドル/兼ね備えAbstractPrintAbstractAccessこの関係は、aとaへの参照/ポインターをAbstractRun 持つという点で、集約(または構成)で抽象化する必要がAbstractRunありAbstractPrintます。これはAbstractRun具体的になるので、名前をに変更しましょうRunner

class Runner
{
public:

    // We now need a constructor to set the references.
    Runner(AbstractAccess& access, AbstractPrint& print) : 
    accessor(access), printer(print) {}

    void run (void) {
        printer.print(accessor.access());          
    }

private:
    AbstractAccess& accessor; // has a AbstractAccess
    AbstractPrint& printer;   // has a AbstractPrint 
};

Access、そしてPrint以前のように定義することができます。

しかし、それらも改善しましょう:

class Print: public virtual AbstractPrint {
    public:
        void print (string s) {                                                                                                                                                                                    
            cout << s << endl;                                                                                                                                                                                     
        }
};

仮想継承必要ありません仮想継承は、ダイヤモンドの問題を解決するために使用されます。しかし、AbstractRunnerが具体的なクラスにされた以上にダイヤモンドはありません。それでは、不要な修飾子を削除しましょう。

class Accessor : public AbstractAccess {
    public:
        string access (void){
            return name;
        }

        void setName(string name) {
            this->name = name;
        }
    private:
        string name;
}; 

class Print: public AbstractPrint {
    public:
        void print (string s) {                                                                                                                                                                                    
            cout << s << endl;                                                                                                                                                                                     
        }
};

さらに、C ++ 11互換のコンパイラをoverride使用している場合は、基本関数をオーバーライドするメソッド修飾子を追加して、基本クラスから取得されたメソッドとそうでないメソッドを区別できるようにすることをお勧めします。

class Accessor : public AbstractAccess {
    public:
        string access (void) override { //overrides  AbstractAcces method
            return name;
        }

        void setName(string name) { //does not override. is a method at Accessor level
            this->name = name;
        }
    private:
        string name;
}; 

ここで、を初期化するときにRunner、具象アクセサーとプリンターを渡す必要があります。これは次のように実行できます。

// Somewhere in a .cpp - file

Accessor accessor;
Print printer;

Runner runner(accessor, printe);

runner.run(); //will call printer and accessor through the references.

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

抽象クラスは別の抽象クラスを継承できますc#

分類Dev

C ++の最終クラスに対してのみ継承を許可する方法はありますか?

分類Dev

C ++の最終クラスに対してのみ継承を許可する方法はありますか?

分類Dev

制限されたAppDomainのC#クラスは、メインのAppDomainにある他のクラスから継承します

分類Dev

C#の依存インターフェースを持つ抽象クラスから継承する正しい方法

分類Dev

C#での継承は、「抽象、外部、または部分としてマークされていないため、本文を宣言する必要があります」

分類Dev

純粋抽象クラスのすべてのサブクラスをC ++の関数に値で渡す方法はありますか?

分類Dev

C ++の抽象クラスは抽象化を意味しますか?

分類Dev

問題を引き起こす基本クラスから継承するC ++の複数のクラス

分類Dev

PowerShellでC#抽象クラスの実装を提供する

分類Dev

C ++では、クラスが継承チェーンの最後のクラス/子であるかどうかを確認するにはどうすればよいですか?つまり、基本クラスの反対側にあります

分類Dev

抽象クラスを実装するC ++

分類Dev

「中間」クラスBを「介して」クラスCに継承された抽象クラスA。仮想機能を宣言する方法は?

分類Dev

C ++ Derivedクラスに継承されないものは何ですか?どうやら、operator =といくつかのコンストラクターは実際に継承されています

分類Dev

C ++の関数から継承されたクラスを返すための最良の方法

分類Dev

C ++で未知の数の変数のコンストラクターを作成する方法はありますか?

分類Dev

C ++で抽象クラスの配列を作成する方法

分類Dev

C ++の抽象クラスと継承

分類Dev

c ++ / cx refクラスに.netのような属性を実装する方法はありますか?

分類Dev

C#クラス/モデルを組み合わせるか、継承を使用して複数のクラスを作成する

分類Dev

C ++の継承、親の代わりに指定されたクラス関数を呼び出しますか?

分類Dev

c ++元の抽象クラス内で、派生クラスの入力を受け取る関数を作成する方法

分類Dev

抽象ベースインターフェイスとその実装の両方を継承すると、C2259が得られます

分類Dev

C ++インターフェイスを介して他のいくつかから継承するクラスを使用する

分類Dev

C ++:クラスから継承すると、クラスは名前空間に取り込まれますか?

分類Dev

Objective CのSwiftクラスから継承する

分類Dev

これらの抽象関数をC#で実装する必要がないのはなぜですか?

分類Dev

基本クラスから継承されたクラスのメソッドを呼び出します。C ++

分類Dev

インスタンスがC#のクラスの汎用バージョンまたは非汎用バージョンから継承されているかどうかを確認します

Related 関連記事

  1. 1

    抽象クラスは別の抽象クラスを継承できますc#

  2. 2

    C ++の最終クラスに対してのみ継承を許可する方法はありますか?

  3. 3

    C ++の最終クラスに対してのみ継承を許可する方法はありますか?

  4. 4

    制限されたAppDomainのC#クラスは、メインのAppDomainにある他のクラスから継承します

  5. 5

    C#の依存インターフェースを持つ抽象クラスから継承する正しい方法

  6. 6

    C#での継承は、「抽象、外部、または部分としてマークされていないため、本文を宣言する必要があります」

  7. 7

    純粋抽象クラスのすべてのサブクラスをC ++の関数に値で渡す方法はありますか?

  8. 8

    C ++の抽象クラスは抽象化を意味しますか?

  9. 9

    問題を引き起こす基本クラスから継承するC ++の複数のクラス

  10. 10

    PowerShellでC#抽象クラスの実装を提供する

  11. 11

    C ++では、クラスが継承チェーンの最後のクラス/子であるかどうかを確認するにはどうすればよいですか?つまり、基本クラスの反対側にあります

  12. 12

    抽象クラスを実装するC ++

  13. 13

    「中間」クラスBを「介して」クラスCに継承された抽象クラスA。仮想機能を宣言する方法は?

  14. 14

    C ++ Derivedクラスに継承されないものは何ですか?どうやら、operator =といくつかのコンストラクターは実際に継承されています

  15. 15

    C ++の関数から継承されたクラスを返すための最良の方法

  16. 16

    C ++で未知の数の変数のコンストラクターを作成する方法はありますか?

  17. 17

    C ++で抽象クラスの配列を作成する方法

  18. 18

    C ++の抽象クラスと継承

  19. 19

    c ++ / cx refクラスに.netのような属性を実装する方法はありますか?

  20. 20

    C#クラス/モデルを組み合わせるか、継承を使用して複数のクラスを作成する

  21. 21

    C ++の継承、親の代わりに指定されたクラス関数を呼び出しますか?

  22. 22

    c ++元の抽象クラス内で、派生クラスの入力を受け取る関数を作成する方法

  23. 23

    抽象ベースインターフェイスとその実装の両方を継承すると、C2259が得られます

  24. 24

    C ++インターフェイスを介して他のいくつかから継承するクラスを使用する

  25. 25

    C ++:クラスから継承すると、クラスは名前空間に取り込まれますか?

  26. 26

    Objective CのSwiftクラスから継承する

  27. 27

    これらの抽象関数をC#で実装する必要がないのはなぜですか?

  28. 28

    基本クラスから継承されたクラスのメソッドを呼び出します。C ++

  29. 29

    インスタンスがC#のクラスの汎用バージョンまたは非汎用バージョンから継承されているかどうかを確認します

ホットタグ

アーカイブ