4

次のケースについて疑問に思っていましたが、どこでも答えを見つけるのに適切な用語がないようです。

一般的なケースから始めましょう: 全部で 3 つのクラスがあります。それらのうちの 2 つは 3 番目のものから継承され、特殊化と見なされます。

現在、これら 3 つのクラスはそれぞれまだ部分的に抽象的であり、それぞれが新しい純粋仮想関数を導入しています。これは、この「クラス構造」がさまざまな目的でさまざまな方法で実装できるためです。そして、これら 3 つのクラスのそれぞれが内部から純粋仮想関数にアクセスするため、後で実装することはできません。

次に、2 番目のクラスの純粋仮想関数の目的を特殊化するために、2 番目のクラスを継承する 4 番目のクラスがあります。5 番目のクラスもあり、3 番目のクラスも同じです。

現在、第 4 および第 5 のクラスに従って特殊化する必要がある、第 1 のクラスの純粋な仮想関数がまだあります。これは私がいくつかの問題を抱えている場所であり、これを解決する2つの方法を考えることができましたが、実際には満足していません.

  • 6 番目のクラスに 1 番目のクラスを継承させ、その目的を 4 番目と 5 番目のクラスのニーズに合わせて特殊化し、それらのクラスに 6 番目のクラスを継承させます。これが「恐怖のダイヤモンド」につながる。

ここに画像の説明を入力

  • 1 番目のクラスから継承しないが、4 番目と 5 番目のクラスに適した特殊な目的を実装する 6 番目のクラスを用意します。次に、4 番目のクラスと 5 番目のクラスを 6 番目から継承し、1 番目のクラスの純粋仮想関数の実装を追加します。これらの実装は、同じパラメーターなどを渡しながら、6 番目の類似の関数を呼び出す以外に何もしません。

ここに画像の説明を入力

「ダイヤモンドの恐怖」を避けたいので、現在、2番目の解決策を検討しています。しかし、それに付随する追加の実装コードは好きではありません。異なる (インターフェース/) クラスを組み合わせる簡単な方法はありませんか?

たとえば、2 番目のソリューションを使用して、1 番目のクラスで宣言されたものと同じ関数プロトタイプを 6 番目のクラスに持ち、1 番目の関数を 6 番目のクラスの関数でオーバーライドする必要があることをコンパイラに伝えるようなことを考えていました。 . 悲しいことにusing myfunction;、4 番目と 5 番目のクラスのクラス宣言内では機能しません。

または一般的な質問: 「インターフェース」を結合する方法はありますか? つまり、クラスの純粋仮想関数は、プロトタイプが同じであり、両方である限り、まったく異なるクラスで定義できることを意味します。子供から受け継いだ。「重い」クラスは必要ないため、コードの重複はできるだけ避けたいと考えています。

このイルミネーションが抽象的すぎる場合は、例を考えます。

€dit:ご意見をお聞かせください: この場合の最善の解決策は何ですか?

4

2 に答える 2

1

最初のアイデアは Avi から生まれましたが、これが最善の解決策であるかどうかはまだわかりません。私はまだそれを投稿して、完全なスレッドを作成します

1stクラスの集合体として6thクラスのインターフェースを持たせます。集約の実際のタイプは、第 4 層 (第 4/5 クラス) で制御されます。ここでは、適切なクラスの定数の動的インスタンスがコンストラクター呼び出しを介して第 1 クラスに渡されます。ポインタはここに格納されます。6 番目のクラスのインターフェイスのみを定義する 7 番目のクラスのポインターになります。また、1 番目のクラスを 7 番目のクラスのフレンドにして、そこからのみインターフェイスにアクセスできるようにしました。

ここに画像の説明を入力

于 2013-04-04T12:46:25.693 に答える
1

最初のソリューションと非常によく似たソリューションを使用します。

  1. 説明したとおりに 6 番目のクラスを作成します。
  2. ここで、Bridge デザイン パターンを使用します。タイプ 1 の 2 と 3 の両方に内部メンバーがあります。クラス 6 のインスタンスをこの内部メンバーに挿入します。
  3. クラス 4 と 5 で欠落している仮想メソッドのトンネル実装を作成します。実装は、6 から具体的な実装を呼び出すだけのワンライナーである必要があります。

お役に立てれば。さらにヘルプが必要な場合は、さらに詳しく説明します。

==============

あなたのコメントに続いて、これが役立つことを願っています:

正確ではありません。最初の解決策を取り、4 と 5 から 6 の継承を削除します (4 は 2 を継承し、5 は 3 を継承し、それだけです)。

クラス 6 は 1 を継承します。クラス 1 - Base と呼びましょう。クラス 4 と 5 の両方に Base 型のメンバーを追加します (これを impl と呼びましょう)。

クラス 4 が foo で、クラス 2 が Base2 だとしましょう。次のようになります (悪い C++ 構文で申し訳ありません。実際の C++ コードを書いてからしばらく経ちます)。

class foo: Base2
{ 
     private Base* impl; 

     public foo(Base* impl) { this.impl = impl; } 

     void virtualMethod() { 
            this.impl->virtualMethod() 
     } 
}
于 2013-04-03T22:24:52.373 に答える