2013-06-09 12 views
13

私は内部使用のためのフレームワークを開発中であり、すべての継承仮想を作ることは、私のクラスを継承している他の開発者にとってダイヤモンドの問題を回避します。すべての継承を仮想化することには欠点がありますか?

ダイヤモンドの問題に直面したときに仮想継承を使用することについて多くの議論がありましたが、それを先取りすることについては何もしていませんでした。

+1

基本クラスの初期化はどうですか?仮想基本クラスは、最も派生した型によって初期化される必要があります。 – dyp

+4

どのような欠点もありませんが、ダイヤモンドの問題を引き起こす人々を喜ばせることを目指すべきではありません。これは、マゾキストであり、爪の鋭利な端を便座に向けて喜ばせることを目指すようなものです。他の人にとって痛いです... –

+0

http://stackoverflow.com/questions/6620497/why-is-single-virtual-inheritance-not-enough-to-resolve-the-dreaded-diamond-prob#6620633 – Nathan

答えて

6

:仮想基底クラスは、ほとんどの派生型で初期化され

  • ascheplerの答えを参照してください)。
  • 仮想継承がある場合は、static_castを使用して派生クラスの参照/ポインタに変換することはできません。 [expr.static.cast]/2、11
  • 派生クラスのポインタ/参照([expr.cast])に変換するCスタイルのキャスト(「明示的な型変換(キャスト記法)」は使用できません)少なくとも、[expr.dynamic.cast]/9の例はそう言います。
  • 仮想基本クラスがあれば、コピーと移動の割り当てとctorは自明ではありません。 "暗黙的に定義されたコピー代入演算子によって、仮想基底クラスを表すサブオブジェクトが2回以上割り当てられるかどうかは不特定である"。
  • 仮想ベースクラスがある場合は、constexprを使用できません。 [dcl.constexpr]/4
  • メンバのポインタへの変換[conv.mem]/2、プレースメント経由のストレージの再利用などの微妙な点があります。this [basic.life]/5,6

仮想基本クラスの実装によっては、他の欠点があるかもしれません。

12

非仮想継承では、各コンストラクタがただちに基本クラスのコンストラクタを呼び出すことに注意してください。しかし、仮想継承では、最も派生したクラスは、すべての仮想基本クラスのコンストラクタを呼び出す必要があります。

基本クラスが初期化を必要とする場合、仮想継承は、ツリーの下のすべてのクラスが正しく初期化する必要があることを意味します。また、ツリーの中間にあるどのクラスも、自分の基本クラスが初期化されていることを期待できません。私は標準で見つかっただけで何

+0

"あなたの基底クラスが初期化を必要とする場合"とは、 "特定の与えられた値への初期化"を意味するか、メンバーが使用されるまでインスタンス化されていない可能性があります。 – user2384250

関連する問題