問題タブ [diamond-problem]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 仮想継承は「ダイヤモンド」(多重継承) のあいまいさをどのように解決しますか?
ダイヤモンドの問題は理解していますが、上記のコードにはその問題はありません。
仮想継承はどのように問題を解決しますか?
私が理解していること:
私が言うA *a = new D();
と、コンパイラーは、型のオブジェクトを型D
のポインターに割り当てることができるかどうかを知りたがってA
いますが、たどることができる 2 つのパスがありますが、それ自体では決定できません。
では、仮想継承はどのように問題を解決するのでしょうか (コンパイラが決定を下すのに役立ちます)。
c++ - 同じ名前の C++ 仮想オーバーライド関数
私はそのようなものを持っています(簡略化)
A の Function () と B の Function() を実装するにはどうすればよいですか? Visual C++ では、特定の関数をインラインで定義することしかできません (つまり、cpp ファイルでは定義できません) が、これは拡張機能だと思います。GCCはこれについて不平を言います。どの関数をオーバーライドするかをコンパイラに伝える標準的な C++ の方法はありますか?
(ビジュアル C++ 2008)
ありがとうございました!
c++ - ひし形のサブ問題: サイド ブランチでの非多重継承には依然としてクラス コンストラクターが必要
仮想継承を使用して、通常のダイヤモンドの問題を通常の方法で「解決」しようとすると、奇妙な問題が発生しました。
ただし、基本クラス A にはデフォルトのコンストラクターがないため、D から手動で呼び出す必要がありました。ただし、このダイヤモンドにクラス E を C 継承として追加しようとすると、
E コンストラクターで A のコンストラクターを手動で呼び出す必要があります。つまり、多重継承もダイヤモンド ACE もありませんが、C は E から A を作成するものではありません。
E から A のコンストラクターを呼び出さずにこの問題を解決することは可能ですか? 適切に行うにはCが必要です:-)。
または、ダイヤモンドの問題をまったく解決しようとしないことは可能ですか?
それでも、Aの2つのインスタンスでクラスDのオブジェクトを宣言しようとしますが、毎回Dから照合するときにコンパイラにCのAを使用するように指示しますか? 追加しようとすると
D の宣言では、明確な基数 A のエラーが発生します。
c++ - C++ - RTTI/dynamic_cast を使用せずに、ひし形の継承オブジェクトをダウンキャストする
現在、非 RTTI プラットフォーム (Android) で多くの RTTI を使用するサードパーティ パッケージの統合に取り組んでいます。基本的に、私は独自の RTTI 実装を行いましたが、問題が発生しています。
問題は、すべてのクラスが同じ基本クラス (オブジェクト) から派生するため、多くのクラスがダイヤモンド継承の問題を抱えていることです。したがって、基本クラスから派生クラスにダウンキャストする場合は、使用する必要があります。 dynamic_cast - ただし、RTTI は利用できません! dynamic_cast を使用しない仮想継承がある場合、オブジェクトを親から子に変換するにはどうすればよいですか?
次のようになります。
それらは私のエラーです:
エラー C2635: 'A*' を 'D*' に変換できません。仮想基本クラスからの変換が暗示されています
error C2440: 'initializing' : 'test_convert::A *' から 'test_convert::D *' に変換できません ベースから派生へのキャストには、dynamic_cast または static_cast が必要です
何か案は?
c++ - C++の奇妙なダイヤモンドの継承の問題
私はこれを持っています
Aには純粋仮想関数があり、次のようにプロトタイプ化されています。
BとCは実質的にAから継承します(class B: public virtual A
、class C: public virtual A
)
Bには、次のようにプロトタイプ化された仮想関数があります。
Cには、次のようにプロトタイプ化された仮想関数があります。
Dは、次のようにBとCの両方から継承しますclass D: public B, public C
。Dには、次のようにプロトタイプ化された仮想関数があります。
さて、コンパイルすると、次の6行のエラーが発生します。
この問題を解決する方法についてはおかしな考えはありません。
前もって感謝します。
c++ - 仮想基底クラスの代入演算子が 1 回だけ呼び出されるようにするにはどうすればよいですか?
典型的なダイヤモンドの問題のように、仮想継承を使用しています。
すべてのクラスに「deep_copy_from」という名前のメソッドを実装しています (ただし、代入 operator=() の場合もあります)。このメソッドは、クラス独自の属性をコピーし、そのコピーを上のクラスに伝達する必要があります。
問題は、D インスタンスをディープ コピーしているときに A::deep_copy_from メソッドが 2 回呼び出されることです (A の「バージョン」は 1 つしかないため、1 回だけ呼び出す必要があります)。一度だけ呼び出されるようにする最善の方法は何ですか?
(B::deep_copy_from と C::deep_copy_from は引き続き同じように動作するはずです)。
サンプルコードは次のとおりです。
現在の出力は次のとおりです。
アップデート:
現在のバージョンは次のとおりです。
出力は次のとおりです。
それよりも良いものを手に入れることはできますか?(つまり、より自動化された)
python - PythonでMixInsを使用するときのダイヤモンドの問題
単純なものを実装する次のコードを検討してくださいMixIn
。
実行main
すると、次のエラーが発生します。
問題は、との両方Story
がStoryHTMLMixin
から派生しobject
、菱形継承問題が発生することです。
解決策は、単に古いスタイルのクラスStoryHTMLMixin
を作成することです。つまり、から継承を削除して、クラスの定義を次のように変更します。object
StoryHTMLMixin
実行すると、次の結果になりますmain
。
古いスタイルのクラスを使用するのは好きではないので、私の質問は次のとおりです。
これはPythonでこの問題を処理する正しい方法ですか、それともより良い方法がありますか?
編集:
最新のPythonソースのクラスUserDict
は、(私の例で示されているように)古いスタイルのクラスに頼るMixInを定義していることがわかります。
すべての人が推奨しているように、MixInを使用せずに、実現したい機能(つまり、実行時のメソッドのバインド)を再定義することに頼ることができます。ただし、要点はまだ残っています。これは、再実装に頼ったり、古いスタイルのクラスにフォールバックしたりせずにMROをいじることができない唯一のユースケースですか?
c++ - インターフェイスの菱形継承問題
私は、純粋仮想関数と仮想(非純粋)デストラクタのみを定義する多くの抽象クラスを使用しています。
仮想継承を使用せずにダイヤモンド継承構造を使用しても問題ありませんか?(一部のプログラマーが仮想継承を使用する必要があることを知らなくても、問題がないことを確認したいと思います。)このトピックの短いが完全な概要を提供する優れたリソースは何ですか?
ありがとう!
c++ - C++/ダイヤモンドの継承/静的変数
私はいくつかの設計上の問題に直面しています、私は書きたいと思います:
クラスCの定義までは問題ないと思いますが、クラスDを定義するとどうなりますか?DはBとCの両方から継承するので、おそらくあいまいなものがあります。私の最終的な目標は、各クラスB、C、およびDに、同じ名前で値が異なる静的変数を設定することです。それは可能ですか?
事前に感謝しますSed
c++ - サードパーティ ライブラリを使用したダイヤモンドの継承問題
「恐ろしい」ダイヤモンドの継承問題に苦しんでいるはずのケースを見つけたようです。ただし、コードは問題なく動作するようです。確かに把握できないように見えるのは、問題がある可能性があるかどうかです。
これがセットアップです。私は MFC を使用しており、マウス クリック ウィンドウ メッセージのカスタム処理を追加するために CEdit を拡張しました。次に、このクラスと、サード パーティの開発者 (この例では Bob と呼びます) によって作成されたクラスを継承します。これにより、自分の特別なコントロールまたはボブのコントロールの拡張バージョンのいずれかを返すことができます。問題は、Bob のライブラリを変更することができず、両方のコードが最終的に CEdit (および CWnd) から継承されることです。
コード例:
だから...質問は次のとおりです。
- これがダイヤモンドの継承問題に悩まされていないように見えるのはなぜですか?
- このデザインには見られない問題があり、将来私を苦しめる可能性はありますか?
- ひし形の片側でコードを変更できない場合 (つまり、両側で CEdit virtual を宣言できない場合)、これを修正する別の方法はありますか?
ありがとう!