2012-02-22 24 views
9

抽象クラスを使用してC++でインターフェイスタイプを定義し、それらを具象クラスで実装しようとしています。私が実行している問題は、別のインタフェースから継承してインタフェースすることも、基本コンストラクトクラスからインプリメンテーションを継承することもできないことです。継承コンクリートクラスを使用したC++でのインターフェイスの実装

私の目標は、あまり複雑でないベースインターフェイスから継承する可能性のあるインターフェイスの階層を定義できるようにすることです。また、具体的なクラスから継承することにより、インターフェースの実装を拡張したいと考えています(下の例のTObjectAを継承しています)。

これは私が持っているものです。私が得ているエラーは "抽象クラス型のオブジェクト"ですTObjectB "は許可されていません"。私は理由を知っていると信じています。なぜなら私はTObjectBにMethodA()を実装しなかったからです。しかし、実際には、基本クラス(TObjectA)によって実装が提供され、それでもインタフェース階層(IInterfaceBはIInterfaceAから継承されます)が必要です。私はまた、継承されたすべてのインタフェースメソッドを派生したconcreateクラスで繰り返す必要はありません。これどうやってするの?あなたのクラス階層、TObjectB

class IInterfaceA 
{ 
public: 
    virtual void MethodA() = 0; 
}; 

class IInterfaceB : IInterfaceA 
{ 
public: 
    virtual void MethodB() = 0; 
}; 

class TObjectA : public IInterfaceA 
{ 
public: 
    void MethodA() { cout << "Method A"; } 
}; 

class TObjectB : public TObjectA, public IInterfaceB 
{ 
public: 
    void MethodB() { cout << "Method B"; } 
}; 

void TestInterfaces() 
{ 
    IInterfaceB* b = new TObjectB(); // error: object of abstract class type "TObjectB" is not allowed 
    b->MethodB(); 
    delete b; 
} 
+2

仮想基本クラスが必要です。例えば。 [参照してください](http://stackoverflow.com/questions/4605556/when-virtual-inheritance-is-a-good-design/4606206#4606206) –

答えて

11

実際には二つのIInterfaceA基本クラスのサブオブジェクトがあります:IInterfaceBTObjectAを通じて継承された1を通じて継承されたものを。それぞれからMethodA()を実装する必要があります。このような複雑なクラス階層があるかどうか

class IInterfaceA 
{ 
public: 
    virtual void MethodA() = 0; 
}; 

class IInterfaceB : public virtual IInterfaceA 
{ 
public: 
    virtual void MethodB() = 0; 
}; 

class TObjectA : public virtual IInterfaceA 
{ 
public: 
    void MethodA() { cout << "Method A"; } 
}; 

class TObjectB : public TObjectA, public virtual IInterfaceB 
{ 
public: 
    void MethodB() { cout << "Method B"; } 
}; 

void TestInterfaces() 
{ 
    TObjectB b_object; 
    IInterfaceB& b = b_object; 
    b.MethodB(); 
} 

あなたは、各インターフェイスクラス型の単一の基底クラスのサブオブジェクトがあることを保証公共仮想継承を使用して、インターフェイスクラスを継承する必要があります望ましいのは別の問題です。

+0

あなたのコードを使用すると、次の警告が表示されます。 "警告: TObjectB ':優位を介して' TObjectA :: TObjectA :: MethodA 'を継承します。私は、ヒープ割り当てられたオブジェクトを使用するテストを変更したときに はまた、私は、実行時のアサーションエラーを取得し、実行が停止します 無効TestInterfacesを(){ IInterfaceB * B =新しいTObjectB(); b-> MethodB(); delete b; } – sysrpl

+0

オブジェクトを多態的に削除する場合は、インターフェイスクラスに仮想デストラクタが必要です。警告に関しては、複雑な継承階層を避けてください。 –

1

あなたの問題は恐ろしいダイヤモンドの継承によって引き起こされます。 TObjectA::IInterfaceA::MethodAを実装しましたが、IInterfaceB::IInterfaceA::MethodAは実装していません。

私は、IIterfaceAとIIterfaceBを完全に独立させることをお勧めします。それが不可能な場合は、仮想継承を調べることができます。

関連する問題