0

具象クラス A と抽象クラス B があるとします。

A と B の両方から継承し、B を実装する具体的な C を考えてみましょう。

class C : public A, public B  
{  
/* implementation of B and specific stuff that belongs to C */  
};

今、私は署名である関数を定義しますvoid foo(B* b);

これは私のコードです。B へのすべてのポインターは A と B の両方であると想定できます。foo の定義では、A へのポインターを取得する方法は? 厄介だが有効なトリックは、次のようにポインターを後方に揃えることです。

void foo(B* b)  
{  
    A* a = reinterpret_cast<A*>(reinterpret_cast<char*>(b) - sizeof(A));
    // now I can use all the stuff from A  
}

Cにはスーパータイプがなく、実際にはCに似た多くのクラスがあり、それらはAとBのみであることに注意してください。私のロジックとこの設計サンプルの両方に自由に質問してください。ただし、質問はポインターの配置のみに関するものです.

4

4 に答える 4

6
void foo(B* b)  
{  
    //A* a = reinterpret_cast<A*>(reinterpret_cast<char*>(b) - sizeof(A)); // undefined behaviour!!!!
    A* a = dynamic_cast<A*>(b);
    if (a)
    {
       // now I can use all the stuff from A  
    }
    else
    {
       // that was something else, not descended from A
    }
}

言い忘れました: 動的キャストを機能させるには、A と B の両方に仮想関数または少なくとも仮想デストラクタが必要です。それ以外の場合、その型変換を行う正当な方法はありません。

于 2011-04-15T07:38:35.567 に答える
2

から派生し、非常に奇妙な設計である、無関係なクラスの膨大なセットを持つAことBA常に「一緒にB使用される」ものがある場合は、それらをマージするか、それらからのみ派生し、そのクラスからのみ派生する shim クラスを導入できます。

class Shim : A, B {};

class DerivedX : Shim {};

後者の場合、最初に fromまたはto に static_castダウンキャストし、次に C++ を使用するだけで、ポインターが他のクラスに暗黙的に変換されます。ABShim*Shim*

于 2011-04-15T07:38:17.620 に答える
0

関数でクラス A とクラス B の両方の機能を使用する場合は、C ポインターを受け取るように関数を変更する必要があります。

void foo(C* c);

そして、一般的に、「すべての B も A である」という仮定は間違っています。クラスAから派生したのではなく、Bインターフェイスから派生したクラスを作成できます。そのため、コンパイラは、特定のケースで「すべてのBがAである」ことを認識しません。

于 2011-04-15T07:49:21.420 に答える
0

Sharptooth の回答を拡張して (書式設定されたコードをコメントに入れることができないため、回答として入力します)、シムを引き続き使用できます。

class Shim : public virtual A, public virtual B {};

それで:

class Derived1 : public Shim, public virtual A, public virtual B1
{
};

class Derived2 : public Shim, public virtual A, public virtual B2
{
};

B1からB2仮想的に派生する必要がありますB

Aしかし、常に と の両方を 実装する必要がある場合はB、両方を継承するか、単一のクラスに統合することにより、両方を備えた単一のインターフェイスを作成する必要があると思います。あなたB1とそれ B2から継承します。( dynamic_castもちろん、 を使用した解決策は、 の派生クラスが から派生する場合とそうでBない場合がありAます。)

于 2011-04-15T08:54:29.770 に答える