2017-02-09 4 views
0

このようなことがあれば、私はある種の「三角継承」問題があります。別の親クラスの仮想メソッドの実装を使用することはできますか?

class System 
{ 
public: 
    Interface() = default; 
    virtual ~Interface() {} 

    virtual void doSomething() = 0; 
    virtual bool somethingDone() const = 0; 

    virtual int trait1() const = 0; 
    virtual bool trait2() const = 0; 
}; 

class SomethingImplementation 
{ 
public: 
    SomethingImplementation() = default; 
    void doSomething() { (void)0; } 
    bool somethingDone() { return true; } 
}; 

そしてIが異なるためのインタフェースのいくつかの実装を持っている:基本的に、私は同様に、インターフェース抽象基底クラスを定義を有し、そのインタフェースの一部に実装を定義するポリシー・クラスケース。いくつかのケースでは、私は単純な実装を使用すると、他の人に私は理解することはできませんどのような彼らに

class SystemA : public System, public SomethingImplementation {/*...*/}; 
class SystemB : public System, public SomethingImplementation {/*...*/}; 
class SystemC : public System, { /* with a custom implementation ... */ }; 

をカスタマイズしたいクラスシステムAまたはsystembのの詳細は、実装作業を行うことがあるかもしれないものです

http://cpp.sh/73r5

ソリューション1

ステートメントを使用して、この場合は何もしていないように見えます。

http://cpp.sh/2nhki

59:13: error: cannot declare variable 'a' to be of abstract type 'SystemA' 
22:7: note: because the following virtual functions are pure within 'SystemA': 
6:18: note:  virtual void System::doSomething() 
7:18: note:  virtual bool System::somethingDone() const 
60:13: error: cannot declare variable 'b' to be of abstract type 'SystemB' 
31:7: note: because the following virtual functions are pure within 'SystemB': 
6:18: note:  virtual void System::doSomething() 
7:18: note:  virtual bool System::somethingDone() const 
63:38: error: invalid new-expression of abstract class type 'SystemA' 

ソリューション2

は、余分なインターフェイスクラスを追加します。 SomethingInterfaceクラスを作成し、SomethingInterfaceからInterfaceSomethingImplementationの両方を継承します。これは問題を通常の「ダイヤモンド継承」問題に変えますが、コンパイラに自分がしたいことをさせることができません。

http://cpp.sh/3dxab

親クラスの仮想メソッドのために別のクラスから実装を使用する方法は何ですか?

+0

仮想継承を試してください。 'class SystemA:public System、public virtual SomethingImplementation'、' class System:public virtual SomethingInterface'などです。 –

+0

同じエラーhttp://cpp.sh/7kroo –

+1

仮想継承はこれとは関係ありません。 SomethingInterfaceとSystemに共通の祖先クラスはありません。 –

答えて

0

あなたはこのようなことをしたいと思います。

// The interface. 
class IInterface 
{ 
public: 
    virtual ~IInterface() {} 
    virtual void method1() = 0; 
    virtual void method2() = 0; 
}; 

// A partial, abstract implementation of interface. 
// This base class implements method1 but leaves method2 unimplemented, 
// which means this class cannot be instantiated. 
class PartialImplementation : public IInterface 
{ 
public: 
    virtual void method1() {} 
}; 

// Full implementation that uses the partial implementation above. 
// method1's implementation is from the base class. 
// method2's implementation is in this class. 
// Because all methods are implemented (directly or inherited), this class can be instantiated. 
class FullImplementation1 : public PartialImplementation 
{ 
public: 
    void method2() {} 
}; 

// Full implementation that uses the partial implementation above. 
// method1's implementation is in this class (overrides base implementation). 
// method2's implementation is in this class. 
// Because all methods are implemented (directly), this class can be instantiated. 
class FullImplementation2 : public PartialImplementation 
{ 
public: 
    void method1() {} 
    void method2() {} 
}; 

// Full implementation that DOES NOT use the partial implementation above. 
// method1's implementation is in this class. 
// method2's implementation is in this class. 
// Because all methods are implemented (directly), this class can be instantiated. 
class FullImplementation3 : public IInterface 
{ 
public: 
    void method1() {} 
    void method2() {} 
}; 

int main() 
{ 
    FullImplementation1 i1; // OK 
    FullImplementation2 i2; // OK 
    FullImplementation3 i3; // OK 

    IInterface* p1 = new FullImplementation1(); // OK 
    delete p1; // OK 

    IInterface* p2 = new FullImplementation2(); // OK 
    delete p2; // OK 

    IInterface* p3 = new FullImplementation3(); // OK 
    delete p3; // OK 

    return 0; 
} 
+0

インターフェイスを実装していない 'PartialImplementation'を使うこともできます。次に、完全な実装上に明示的にインタフェースを実装する必要があり、それらのメソッドの実装では、基本部分実装のメソッドを呼び出すことができます。 –

+0

他のコメント作成者が述べたように、ここにはダイアモンドの継承はなく、仮想継承は必要ありません。単一の完全実装のベースとして使用しようとしている部分実装が複数ある場合は、仮想継承を使用してダイアモンド継承を作成できます。 –

0

私はダイヤモンドの継承を見てきたすべての例があるため、IS-Aの誤解の悪い設計からだったと関係-AのHAS。実装を継承しない、実装を継承する(例えば実装を継承する)

SystemAは、Systemから継承し、そのメソッドを呼び出すメンバーとしてSomethingImplementationを持つ必要があります。

ミックスインを調べることもできます。

+0

簡潔な説明をありがとう。それはまさに私がやっていたことです。私はミックスインを調べましたが、それは私が望んだものではないようでした。今はアレクサンドルスクの本を買う時が来たと思う –

関連する問題