プロジェクトでは、ライブラリのインターフェイスから実装の詳細を隠す必要があります。この「効率的な」(コーディングとメンテナンスの面で)私が扱う唯一の方法は、同じ抽象基盤に基づく抽象クラスと具象基底クラスの複数の継承でした。だから、私は拡張されたダイヤモンド構造で終わった。C++多重継承/仮想継承
私は通常、複雑であるため可能な限り複数の継承を避けようとしていますので、使用経験はあまりありませんので、私が試しているデザインに落とし穴がありますか?監督しません。
基本的に私は複数の「ツール」を用意する必要があります。これらの「ツール」にはもちろん、インターフェイスABCを使用して非表示にしたい実装の詳細があります。例:
class Tool1Impl:public ITool1;
クラスTool2Impl:public ITool2;
もちろん、ツールにはいくつかの共通点があります。
私は共通の基本クラスを持ちたいと思いますが、インプリメンテーションの詳細はインターフェイスで再度隠す必要があります。
私は、次の(ダイヤモンド)方式を思い付いた:
ITool
/ | \
/ | \
/ | \
ITool1 ToolImplBase ITool2 ... IToolN
\ / \ /
\ / \ /
\ / \/
ToolImpl1 ToolImpl2 ... IToolImplN
ToolImplBaseはのiToolの純粋仮想機能を実装しています。 ToolImpl1は、ITool1で宣言された純粋な仮想機能を実装します。
実装のアウトラインは以下のようになります。
class ITool {
public:
virtual int common_foo(int a) = 0;
};
class ITool1 : public virtual ITool {
public:
virtual int specific_foo(int b) = 0;
};
class ITool2 : public virtual ITool {
public:
virtual int specific_bar(int c) = 0;
};
class ToolImplBase : public virtual ITool {
public:
virtual int common_foo(int a) override;
protected:
int _some_common_data;
};
class ToolImpl1 : public ToolImplBase, public virtual ITool1 {
public:
virtual int specific_foo(int b) override;
private:
int _some_specific_data;
};
class ToolImpl2 : public ToolImplBase, public virtual ITool2 {
public:
virtual int specific_bar(int c) override;
private:
int _some_specific_data;
};
私がやりたいようだが、これですべての潜在的な落とし穴や明白な問題があった場合、私はわかりません。私は、もし私が継承スキームのすべての権利(仮想メソッドではなく ":public virtual")で "仮想"を取得しているかどうかもわかりません。
warning C4250: 'ToolImpl1': inherits'ToolImplBase::ToolImplBase::common_foo' via dominance
は、私はちょうどそれを無視することができます: 1つの問題は、MSVCは(私が原因。この時点で、いくつかの外部depenciesに2010とこだわっている)私のコンパイラの警告C4250を与えること、ありますか?なぜcommon_fooへの非支配的な方法は純粋な仮想であるので、私はなぜこれを得ているのかは分かりません。したがって、実際には有効でない "支配的でない"実装はありません。任意の入力のための
おかげで(を除いて「は M.I.を使用することはありません」、私はすでに、可能な限りそれを避けるためにしようとしています)。
私の小さなビット以下のように
IToolX
インターフェイスを変更します:必要なときにMIを使用すること自由に感じていますがダイヤモンドを持っているとき、あなたは間違った道に、おそらくです。あなたは、意味の代わりに結果を得るために継承を使用していないと確信していますか? ToolImplBaseの2つのことを考えてみましょう(例は架空のものなので、これ以上は言えません):構成と私的継承。 –この例は架空のものではなく、実際のコードのものですが、もちろん簡略化されています。あなたはここでそのコンポジションをどのように使用しますか? ToolImplFoo内のIToolからの共通の機能をすべてToolImplBaseに委譲するだけですか? –
C4250関数 'common_foo'は2つのパスに継承されており、異なる実装を持っています。最終形式で実装する必要があります – Danh