4

このサイトのほとんどの人は、次の 2 つの方法で実装を外部委託できることに同意すると思います。

  • 私的遺産
  • 構成

継承は、ほとんどの場合悪用されます。特に、パブリック継承は、別のフォームまたは継承の方が優れている可能性がある場合によく使用され、一般に、プライベート継承ではなく合成を使用する必要があります。

もちろん、通常の警告が適用されますが、実装の問題のために継承が本当に必要な場合はいつでも思いつきません。

ただし、Boost パラメータ ライブラリの場合、名前付きパラメータ イディオム (コンストラクタ用) の実装のために、構成よりも継承が選択されていることに気付くでしょう。

私が見ることができる仮想メソッドがここで動作していないため、古典的な EBO (Empty Base Optimization) の説明しか思い浮かびません。

誰かがよく知っているか、私を議論にリダイレクトできますか?

ありがとう、マチュー。

4

2 に答える 2

2

編集おっと!あなたの投稿を読み間違えたので、以下に回答を投稿しました。Boostライブラリは継承よりもコンポジションを使用しているとおっしゃっていたと思いますが、その逆ではありません。それでも、それが誰にとっても役立つのであれば...(私があなたの質問の答えになると思うものについては、EDIT2を参照してください。)

Boostパラメータライブラリの具体的な答えはわかりません。ただし、通常はこれがより良い選択であると言えます。その理由は、複数の方法で関係を実装するオプションがある場合は常に、最も弱いもの(低結合度/高凝集度)を選択する必要があるためです。継承は構成よりも強いので...

プライベート継承を使用すると、例外安全コードの実装も困難になる場合があることに注意してください。operator==たとえば、を考えてみましょう。コンポジションを使用すると、一時的なものを作成し、コミット/ロールバックロジックを使用して割り当てを行うことができます(オブジェクトが正しく構築されていることを前提としています)。ただし、継承を使用する場合は、派生クラスのBase::operator==(obj)内部のようなことを行う可能性があります。operator==そのBase::operator==(obj)呼び出しがスローされた場合、あなたはあなたの保証を危険にさらします。

編集2: 今、あなたが本当に尋ねたことに答えようとしています。これはあなたが提供したリンクから私が理解できたものです。ライブラリの詳細がわからないので、間違っている場合は訂正してください。

「の観点から実装」にコンポジションを使用する場合、委任に対して1レベルの間接参照が必要です。


struct AImpl 
{ 
  //Dummy code, just for the example.
  int get_int() const { return 10; }
};

struct A { AImpl * impl_; int get_int() const { return impl->get_int(); } /* ... */ };

パラメーターが有効なコンストラクターの場合、実装クラスを作成する必要がありますが、それでも「ラッパー」クラスを透過的に使用できるはずです。これは、あなたが言及したリンクの例では、myclass操作するのと同じように操作できることが望ましいことを意味しますmyclass_impl。これは、継承を介してのみ実行できます。(この例では、継承が構造体のデフォルトであるため、継承がパブリックであることに注意してください。)

myclass_impl「実際の」クラス、データ、動作などを含むクラスであると想定します。次に、そのようなメソッドがありget_int()、継承を使用しなかった場合は、get_int()ラッパーを作成する必要がありmyclassます。私が上でしたように。

于 2009-09-28T15:43:08.283 に答える
0

これは私が今まで使用したライブラリではないため、リンク先のドキュメントを一目見るだけで、この回答の基になっています。私が間違っている可能性は十分にありますが...

彼らは、共通の基本クラスを使用する理由として、コンストラクターの委任について言及しています。コンポジションがその特定の問題にも同様に対処できることは間違いありません。ただし、すべてを単一の型に入れるとうまくいきません。彼らは、複数のコンストラクター シグネチャを 1 つのユーザー作成の初期化関数にまとめ、2 番目のデータ型を必要とするコンストラクターの委譲を必要としないことを望んでいます。ライブラリの多くは、すべてをクラス自体に組み込むという観点からすでに作成されているのではないかと私は考えています。コンストラクター委任の問題に遭遇したとき、彼らは妥協しました。それを基本クラスに入れることは、以前の機能で行っていたことにおそらく近いものでした。そこでは、機能のインターフェイスと実装の両方の側面が、作業しているクラスからアクセスできることがわかっていました。

私は決して図書館を非難しているわけではありません。このようなライブラリを妥当な時間内にまとめることができるかどうかは非常に疑わしい. 行間を読んでいるだけです。無知から言って、実際に何かを知っているふりをしています。:-)

于 2009-09-28T19:14:50.097 に答える