2010-11-26 11 views
11

私はこれよりもはるかに複雑なクラス構造を持っていますが、その本質にまで問題を沸騰、これは私のシナリオを説明します。私は2つのクラス、& Bを持って、その純粋仮想基底クラスを実装その共通の祖先を、そして純粋仮想ベースで一般的な方法で充填& B.最後に、テンプレートクラスをCOM-断定第3クラスC:あいまいな継承:

struct I { 
    virtual void r()=0; 
}; 

struct A : I {}; 
struct B : I {}; 

struct C : A, B { 
    void q(){ 
    r();    // the problem is here. 
    } 
}; 

struct D : C { 
    virtual void r(){ 
    } 
}; 

C* c = new D; 
c->q(); 

私の問題は、私ができる、ありますr ::を呼び出すためにC :: qを得る方法はありません。

void C::q(){ 
    r(); // is ambiguous 
    A::r(); // is pure virtual 
    B::r(); // also is pure virtual 
    D::r(); // C doesn't know about D 
    ((D*)this)->r(); // is dubious and requires C to know about D. 
} 

正しい仮想メソッドが呼び出されるように、Cからr()メソッドを呼び出すにはどうすればよいですか?


申し訳ありませんが、ここでは仮想継承を使用できないことを明確にする必要があります。どちらも、すべてが解決するために十分に()Rへの呼び出しを明確に見える

struct C : A, B { 
    virtual void r()=0; 
    ... 

OR

struct C : A, B { 
    using A::r; 
    ... 

:私は2つの解決策を発見しました。

はCで
+6

+1あなたの問題を解決し、最も簡単な形式に分解してください。 –

+0

r()は仮想継承なしでCであいまいにならないでしょうか? – DumbCoder

+0

仮想基本クラスか抽象基本クラスのみを意味しましたか?'I'を仮想ベースにするためには' struct A:virtual I {}; 'と' struct B:virtual I {}; 'が必要です。 –

答えて

4

再宣言方法Rと純粋仮想:

struct C : A, B { 
    void q(){ 
    r();    // the problem is here. 
    } 

    virtual void r()=0; 
}; 
+1

これがなぜ受け入れられた答えであるか分かりません。それはハックです。正解はIから実質的に継承されています。 – T33C

+0

通常、私は同意します。しかし、私の状況では私は仮想継承を使うことができません。すべての非仮想継承ソリューションのうち、これは最もエレガントです。 –

2

階層の一部が従うようにコンパイラに教える:

struct C : A, B { 
    void q(){ 
    A * p = this; 
    p->r();    // recent GCC compiles this 
    } 
}; 
3

てみ仮想継承

struct A : virtual I {}; 
struct B : virtual I {}; 
2

それは曖昧ですコンパイラは、r()がコールするもの、Aから来るもの、またはone com

static_cast<A*>(this)->r(); 

または

static_cast<B*>(this)->r(); 

しかし、私はこれのどれもあなたが探している答えではないと思います:B.

からINGの簡単な方法は、書くことです。あなたは、私がvirtualを通じてインタフェースを継承して、状況をクリーンアップ:

struct A : virtual I {}; 
struct B : virtual I {}; 

、あなたが期待どおりに

void C::q() { r(); } 

を呼び出すことができます。 単純なの説明は、仮想を使用することによって、クラスCはインターフェイスIの1つだけ "コピー"を取得し、2つではありません。これにより、コードが曖昧になります。

+0

static_castではなくdynamic_castを使用するべきですか?仮想関数が含まれています。 – DumbCoder

+0

いいえ、階層を上向きにし、下向きにしません。 – Simone

-1

子構造体にr()をオーバーロードしていないので、まだ純粋な仮想です。実装がない。

+0

いいえ、それは問題ではありません。 – Simone

関連する問題