0

私はいくつかの設計上の問題に直面しています、私は書きたいと思います:

class A { ... };
class B : public A { static string type_; ... };
class C : public A { static string type_; ... };
class D : public B, public C { static string type_; ... };

クラスCの定義までは問題ないと思いますが、クラスDを定義するとどうなりますか?DはBとCの両方から継承するので、おそらくあいまいなものがあります。私の最終的な目標は、各クラスB、C、およびDに、同じ名前で値が異なる静的変数を設定することです。それは可能ですか?

事前に感謝しますSed

4

4 に答える 4

3

ここにあるコードはまったく問題ありません。クラスは、親クラスのメンバーの名前と一致する場合でも、任意の名前でメンバーを定義できます。問題が発生するのは、これらの名前のいずれかを使用するとあいまいさが生じる場合のみです。

あなたの場合、クラス、、およびstaticに 3 つのデータ メンバーがあっても問題は発生せず、各クラスの のインスタンスは他のすべてのインスタンスとは異なります。名前が同じだからといって、C++ がそれらをオーバーライドとして扱うわけではありません。オーバーライドできるのはメンバー関数のみです。BCDtype_virtual

各クラスとそのメンバー関数のコンテキスト内では、 へname_の参照は常にそのクラスの を参照しますname_。これは、クラスがその基底クラスから名前を隠し、コンパイラが現在のクラスのみを検索するためです。、 などのname_完全修飾名でフィールドをグローバルに参照できます。A::name_B::name_

さらに重要なことは、ここで使用する継承のタイプは、仮想か非仮想かに関係なく、ここで問題になっているのは変数の名前付けだけであるため、問題ではありません。static各データ メンバーのコピーは 1 つしかないため、クラスが最終的Dに の 2 つのコピーを継承するかどうかA::name_は問題ではありません。存在するのは 1 つだけなので、2 つのコピーを継承することはできません。

于 2011-03-05T10:57:40.527 に答える
0

type_にメソッドを書き込むと、 'sDに解決されます。またはを書き込むと、それぞれのインスタンスのに解決されます。Dtype_A::name_B::name_type_

type_別の注意点として、各クラスで静的フィールドが呼び出されているため、ある種のリフレクションシステムをC++にハッキングしようとしているように見えます。これはまれな状況では役立つかもしれませんが、おそらく悪い考えです。

于 2011-03-05T11:31:46.837 に答える
0

そこにはまったく曖昧なものはありません。B::type_両方のフィールドをおよびとして参照できますC::type_

于 2011-03-05T10:57:47.987 に答える
-1

ダイヤモンド継承では、あいまいさを避けるために C++ 標準によって提供される 1 つの解決策があります。

クラス定義の構造は次のようになります

                       A
                      /  \
                     /    \
                    /      \
                   B        C
                    \      /
                     \    /
                      \  /
                       D 

クラスBでクラスAを継承するときは、次を使用します

class B : public virtual A

Cクラスも同じ。

したがって、いずれかのクラスがクラス B および C から継承する場合、クラス A のインスタンスは 1 つだけになります。

クラス D の仮想継承は必要ありません。効果はありません。

クラス D のサイズは以前と同じかもしれませんが、D のインスタンスを作成すると、クラス B とクラス C からの変数アクセスのアドレスはすべて同じになります。

于 2011-03-05T11:11:40.463 に答える