基本クラスの仮想継承が、複数の派生クラス間で共通の共有基本クラスを作成し、DDD問題に対処することを理解します。ベースクラスに派生クラスが1つしかない場合、ベースを仮想的または非仮想的に継承すると違いがありますか?基本的には、クエリIs it possible to forbid deriving from a class at compile time?で説明されている説明を理解しようとしています。Usage_lock基本クラスは、Usableというクラスの派生を防ぐために事実上継承されています。この仮想キーを削除すると、動作が変わります。つまり、Usableからサブクラスを派生させることができます。ですから、私は単一の継承シナリオで仮想キーの違いを理解したいと思います。単一の仮想継承
単一の仮想継承
答えて
仮想基本クラスは、最も派生したクラスによって構築されます。事実上派生し、そのような基底のコンストラクタを非公開にすることによって、別のクラスがそれを構築する方法がないため、派生を効果的に防ぐことができます。しかし、それは非常に人工的な構造物であり、それにはあまりにもオーバーヘッドがあります。
単一の仮想継承の主な違いは、最も派生したクラスだけが仮想的に継承された基底のコンストラクタを呼び出し、他のすべてのクラスは構築されたクラスへの参照が提供されることです(これは裏側で起こります) 。
そうで、この例では、さらにUsable
を導出しようとするので、(プライベートで)Usable_lock
コンストラクタを呼び出すために新しいクラスを必要とする、それがUsable
由来する任意の他のクラスのために不可能です。ロック対象の友人であるため、Usable
のみがロックオブジェクトを構築できます。
仮想継承は基本的にDiamond shaped Inheritance
の古典的な問題を解決するために導入されました。
は、次のクラスを考えてみましょう。ここ
class Base {};
class Derived1: Base {};
class Derived2: Base {};
struct MostDerived: Derived1, Derived2 {};
MostDerived
クラスがあるため、この菱形の階層のBase
の2のインスタンスを持っています。
この問題を解決するために、C++はvirtual
キーワードを使用し、仮想継承という概念を導入しています。
したがってとして、ここではvirtual
キーワードを追加:
class Derived1: virtual Base {};
class Derived2: virtual Base {};
は今だけBase
MostDerived
内部クラスのインスタンスが1つになることを保証します。
MostDerived
クラスは、このコンストラクタを呼び出すことによってBase
クラスのインスタンスをインスタンス化します。上記背景と
(太字のテキストを強調)、コード例については、以下の点を考慮してください。派生クラスUsable
MUSTオブジェクトのUsable_lock
基本クラスをインスタンス化するよう
Usable
クラスは、Usable_lock
から実質的に導出しますそのコンストラクタを呼び出すことによって。
しかし、Usable_lock
クラスにはプライベートコンストラクタがあり、クラス自体がコンストラクタにアクセスできるため、他のクラスがそれから派生するのを防ぐことができます。C++ 03標準から
リファレンス:
セクション12.6.2初期化塩基およびメンバー
パラグラフ6:仮想基本クラスを表す
すべてのサブオブジェクトであります最も派生したクラス(1.8)のコンストラクタによって初期化されます。最も派生したクラスのコンストラクタが仮想基本クラスVのmem初期化子を指定していない場合、Vのデフォルトコンストラクタが呼び出され、仮想基本クラスのサブオブジェクトが初期化されます。 Vにアクセス可能なデフォルトのコンストラクタがない場合、初期化は正しく行われません。仮想基本クラスの名前を付けるmem初期化子は、最も派生したクラスではないクラスのコンストラクタの実行中は無視される。
これをdownvotingする*本当の*理由は? –
- 1. 仮想継承
- 2. C++仮想継承
- 3. C++多重継承/仮想継承
- 4. 仮想関数の継承
- 5. 連合仮想継承
- 6. 継承と仮想関数
- 7. 仮想多重継承
- 8. 仮想継承し、デフォルトコンストラクタ
- 9. 仮想クラスや継承C++
- 10. 基底クラスの仮想および非仮想継承ミキシング
- 11. 複数の仮想継承の曖昧
- 12. 仮想継承のパフォーマンスへの影響
- 13. 仮想継承のコンストラクタの順序
- 14. 継承クラスのC++仮想関数
- 15. 基底クラスからの仮想継承
- 16. 仮想継承 - なぜこの出力
- 17. 複数の仮想(ダイヤモンド)継承
- 18. 仮想と非仮想多重継承(C++)
- 19. 純粋仮想継承、多重継承、およびC4505
- 20. C++複数テンプレート純粋仮想継承
- 21. 仮想継承と機能メンバー
- 22. 仮想基底クラスと継承
- 23. 仮想継承とパラメータ化コンストラクタ
- 24. 継承と仮想メンバ関数
- 25. 単一テーブルの継承クエリ
- 26. NHibernate単一テーブルの継承
- 27. Azure単一仮想マシンSLA
- 28. 仮想基本クラスから継承する仮想関数の「仮想サンク」とは何ですか?
- 29. Has_and_belongs_to_manyと単一テーブル継承
- 30. Flask-SQLAlchemy単一テーブル継承
おかげで、私は基本コンストラクタにブレークポイントを設定することで、それを見ることができます。ありがとうございました。 – irappa