2011-06-27 26 views
7
class A { 
    public: 
     void fa() { 
     } 
    }; 

class B : public A{ 
public: 
    void fb() { 
    } 
}; 

class C : public A, public B { 
public: 
    void fc() { 
     //call A::fa(), not B::A::fa(); 
    } 
}; 

C::fc()からの呼び出し方法A::fa()派生クラスの基本クラスメンバを参照してください

GCCはdirect base A inaccessible in C due to ambiguityと警告します。これは、基本クラスのメンバを直接参照する方法がないことを意味しますか?

+0

があなたの現在のコードではありません意味

A class shall not be specified as a direct base class of a derived class more than once. [Note: a class can be an indirect base class more than once and can be a direct and an indirect base class. There are limited things that can be done with such a class. The non-static data members and member functions of the direct base class cannot be referred to in the scope of the derived class. However, the static members, enumerations and types can be unambiguously referred to. 

'クラスB'は'クラスA'を継承しません。あなたは、更新されたコード? – iammilind

+0

私のミスを入れている:)今は固定されています – MKo

+1

'C'のための' A'基本クラスのサブオブジェクトか、 'A'から派生する' C'と 'B'からの' B'からの2つの 'A'基本クラスのサブオブジェクトが必要ですか? 'A')?今は2つありますが、どちらがあなたの意図であるかもしれません。 –

答えて

0

あなたはこのような問題を克服するためにvirtual継承を使用することができます。

class B : virtual public A { 

さて、あなたは、単に子供class CA::fa()を使用することができます。

void fc() 
{ 
    fa(); 
} 

BはすでにAを継承public味方であるときしかし、私は一般的に、class Cに再びclass Aを継承するために実用的な必要性が表示されません。だから、あなたのケースでは、あなたはそれを簡単にすることができます

class C : public B { 

編集

あなたはAための2つのインスタンスをしたい場合。そして、あなたが意図している直接のインスタンスはCの対象とすることができる。持つ

class C : public B { 
    A obj; 

、ので直接継承Aとにかくで使用できません。 Cのスコープ内でポインタまたは参照を宣言することはできません。

+0

これは実用的ではない、私はちょうどこれを行う方法があることを知りたいですか?ところで、仮想継承の場合、1つのA基本クラスがあり、あいまいさはありません。 – MKo

+0

@MKo、私はすでに私の編集した答えに言及しました。あなたの場合、 'C'に' A'を継承する必要はありません。また、長期的には悪い設計を証明するかもしれません。 – iammilind

1

私はちょうどあなたのC::fc()関数から()A::fa()がFAを呼び出すのに十分です入れ、codepad.orgであなたのコードをコンパイルしました。

void fc() { 
     A::fa(); 
    } 

以下は、あなたのコードとコードパッドのリンクです。

http://codepad.org/NMFTFRnt

+0

私はどのコンパイラコードパッドが使用されているのかわかりませんが、clang 3.0/133044とg ++ 4.5.1はどちらもそれを拒否します。 –

+0

@James McNellis:はい、それは**コンパイラの問題**に関連しています**言語自体ではありません。 – Jhaliya

+0

'B'はあなたのコードで' A'から派生しないので、コンパイルします。 –

8

一つのオプションを使用すると、右の基本クラスのサブオブジェクトにキャストするために使用できるスタブクラスを作成するには、次のようになります。

implicit_castは次のように定義されて
struct A { 
    void fa() { } 
}; 

struct B : A { 
    void fb() { } 
}; 

// Use a stub class that we can cast through: 
struct A_ : A { }; 

struct C : A_, B { 
    void fc() { 
     implicit_cast<A_&>(*this).fa(); 
    } 
}; 

template <typename T> struct identity { typedef T type; } 

template <typename T> 
T implicit_cast(typename identity<T>::type& x) { return x; } 
+0

私は認めます。疑問に困惑しており、スタブクラスをラティスに注入しないでこれを行う方法があるかどうかに関して非常に興味があります。 –

+0

スタブを使用するのは素晴らしい回避策ですが、このようなトリックがなければこの動作を達成する方法はないと思います。それは私が一度も考えていない言葉の限界です! –

+0

なぜstatic_castの代わりに 'implicit_cast'を使用していますか?私は私の質問に答えるSOの投稿を見つけますが、あなたはおそらくそれについて少しの説明やリンクを追加することができます。 –

0

私はあなたが望むことができるとは思わない。ここにあいまいさがあります:A::fa()と言うとき、それはまだAオブジェクトをコンパイラに伝えません。クラスAにアクセスする方法はありません。それは警告があなたに言っていることです。

これは非常に奇妙な構造のようです。 is-a関係には公開継承を使用する必要があります。 Cは-Aです。それは意味をなさない。これは実際には決して上手くいかない人工的な例か、この設計を再考すべきであることを示唆しています。

5

ISO C++ 2003標準(10.1)から次の情報が見つかりました。3)それは直接的な方法:(

関連する問題