-2

C++ の仮想継承は、ひし形の問題を防ぐ便利な方法です。ただし、すべての場合に適切に機能させることはできないようです。

これを説明するのは非常に難しいと思いますが、うまくいくことを願っています。問題を提示しましょう:

A は B を継承します。A は、C というクラス セットと D という別のクラス セットの基本クラスです。

問題は、クラスの C セットが B を中心に共通の機能を持っていることです。

私がやりたいことは不可能ですが、事実上Bを継承し、Cによって継承されるクラスEです。問題は次のとおりです。

この場合、A は事実上 B を継承していないため、機能しません。

A が事実上 B を継承する場合、D のすべてのクラスで B のコンストラクターを使用する必要があります。

結論:どの場合でも、重複したコードがあります。コードを複製せずにこの問題を解決するにはどうすればよいですか?

4

2 に答える 2

1

Bインターフェイス部分IB(抽象基本クラス、データ メンバーなし) と実装部分に分割しBimplます。乗算継承のみ IBIBにはデータ メンバーがないため、デフォルト以外のコンストラクターは必要ないため、どこでも繰り返す必要はありません。

Cこの変更により抽象化された階層内の各クラスに対して、 と の両方をCimpl継承する を作成します。から継承することはありません。の非デフォルト コンストラクタ (以前は ) は、でのみ呼び出されます。CBimplCimplBimplBC

于 2013-08-10T18:50:25.767 に答える
1

さて、あなたはあなたが持っていると言っています:

                             B
                             +
                             |
                             v
                             A
                             +
                        +----+----+
                        v         v
                        C         D

これらはすべて非仮想継承であり、仮想的に継承するクラスとそれをE継承するBクラスがCあるため、完全な図は次のようになります。

                +-----------+B
                |            +
                |            |
                v            v
                E            A
                +            +
                +---+---+----+----+
                    v             v
                    C             D                                  

によって仮想的に継承される例外がBあります。E

解決策は簡単で、A事実上継承も行う必要がありBますが、あなたの質問から、変更できないことがわかりAました。次のオプションは、C継承するAE、他のインスタンスを作成することです。これは委任と呼ばれます。E別の方法として、共通のインターフェイスを提供し、そのC使用する すべての機能を備えたインターフェイス (純粋な仮想クラス) を作成し、そのインターフェイスを作成CしてE派生させることができるポリモーフィズムを許可することができます。Eインターフェイスから仮想関数を実装し、Cはそれを関数呼び出しとして実装しますEの実装。または(推奨されません)、問題がなければ死のダイヤモンドと一緒に暮らすこともできますが、それを判断するのは難しいので、これはひどい考えなのでお勧めしません.

于 2013-08-10T18:42:17.640 に答える