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