(ここでダイヤモンドと仮想の継承に関する質問を検索して読みましたが、答えを見つけることができませんでした。私の考えでは、この状況は少し異常であり、私の要件が多少ずれているという考えを喜んで受け入れるつもりです。オン一方、これは「いい」方法で実行できるはずだと思います。)
状況と要件:
私は、自分では制御できず、変更できない C++ クラス ライブラリを持っています。クラスを定義しWindow
ます。クラスには、派生クラスが使用することを意図した、他の方法ではアクセスできないWindow
保護されたメンバー (たとえば: ) があります。何百もの(まあ、非常に多数の...)メソッドを定義しています。handle
Window
に機能を追加してWindow
、派生クラス (私が書いた; と言うLogWindow
) が自動的に持つようにしたいと考えています。このような機能の例として、ウィンドウを相互にスナップする機能があります。これを実装するには、Window
の保護されたhandle
メンバーにアクセスする必要があります。
私の実際の目的にはこれで十分であり、解決策はSnappableWindow
簡単です。Window
Window
LogWindow
SnappableWindow
しかし、私が本当に欲しいのは、よりきれいな私見ですが、次のとおりです。
- この「Snappable」機能をスタンドアロンのコードとして持つ機能。他の
Window
派生クラスに「プラグイン」するかどうかを選択できます。 - この概念を他の機能にも拡張する機能 (たとえば、ウィンドウを最小化する機能)。したがって
Window
、「スナップ可能」機能の有無にかかわらず、「最小化可能」機能の有無にかかわらず、派生クラスを持つことができます。 - 「SnappableWindow」と「MinimizableWindow」の実装は、どちらも
Window
のhandle
保護されたメンバーにアクセスする必要があります。 - 「スナップ可能」と「最小化可能」を実際のクラス宣言の一部にして、実際のクラス (
LogWindow
) が「ウィンドウ」、「スナップ可能ウィンドウ」、「最小化可能ウィンドウ」になるようにしたいと考えています。
...そして今、質問に:
SnappableWindow
andMinimizableWindow
を宣言することでこれを行う方法を理解しますから派生するのではなく、コンストラクターでWindow
a を取得し、と の任意の組み合わせから派生します。handle
LogWindow
Window
SnappableWindow
MinimizableWindow
編集:の init()を呼び出した後、LogWindow のコンストラクターの途中handle
で初期化されます。(前に述べたように、 のコンストラクターの途中ではありません)。Window
Window
Window
ただし、handle
は のコンストラクタの途中でしか初期化されないため (のLogWindow
を呼び出した後)、のコンストラクタ初期化リストの一部としておよびに渡すことはできません。むしろ、両方で何らかのメソッドを明示的に呼び出して、 . そして、これは、私の派生クラスのそれぞれにあります。( 、、など)Window
init()
SnappableWindow
MinimizableWindow
LogWindow
init()
handle
Window
LogWindow
SearchWindow
PreferencesWindow
次のようなことができる方法を探しています。
クラス LogWindow : public Window、public SnappableWindow、public MinimizableWindow
... 内に他のものを実装する必要はありませんLogWindow
。仮想継承をいじりましたが、解決策が思いつきません。