問題タブ [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.

0 投票する
3 に答える
254 参照

c++ - C++ の仮想基本クラス

仮想基底クラスについて質問があります。多重継承における「恐ろしいダイアモンド オブ デス」/あいまいさの問題を解決するために、仮想基底クラスが導入されました。

宣言でキーワードvirtualが使用されていない場合はどうなりますか。class C詳しく説明していただけますか?

0 投票する
1 に答える
803 参照

c++ - 仮想関数を持つ複数の継承クラスから派生したクラスのサイズ

以下のひし形のシナリオを考えてみましょう。

  • Baseのサイズは8 [ x(4) + vptr(4) (仮想デストラクタから) ]
  • Derived1のサイズは16 [ x(4) + y(4) + vptr(4) (仮想デストラクタから) + vptr(4) (仮想継承から) ]
  • Derived2のサイズは16 [ x(4) + z(4) + vptr(4) (仮想デストラクタから) + vptr(4) (仮想継承から) ]
  • Derived3のサイズは28 [ x(4) + y(4) + z(4) + t(4) + vptr(4) (仮想デストラクタから) + 2 x vptr(4) (Derived1 と Derived2 の仮想継承から) ) ]

ここで、 Derived 3から派生した別のクラスDerived4を追加すると、

サイズは32になります (これは Derived3 + s のサイズであると想定しています)。

Derived4内に仮想ポインタがないかどうか知りたいですか?

通常のクラス階層 (ひし形構造なし) を使用する場合、基本クラスに仮想関数がある場合、すべての派生クラスには vptrs があります。では、なぜこの場合ではないのでしょうか。

GNU GCC コンパイラを使用して codeBlocks 12.11 のコードをコンパイルしています。

0 投票する
1 に答える
341 参照

c++ - ひし形の範囲

点が菱形の範囲内にあるかどうかをチェックする関数を作りたいのですが、

この範囲をひし形にする方法は長方形の範囲になりますか?? 、ここで、位置は中央、高さ = 120 幅 = 200

0 投票する
1 に答える
883 参照

c++ - ダイヤモンドの継承を避ける

クラスがありAます。

クラスBとクラスCから派生したインターフェイスですA

ここで、 との両方のクラスDとを実装する必要があります。EBC

そして、いくつかのクラスがあります: FDBGDCHECIEBJDBKDCLEB(これらのクラスの名前の最後MECにあるDBDCは、クラスが、 、for 、forなどの末尾にandDを使用することを意味します。BDBDCDCEBEB

それで:

しかし、私はダイヤモンドの継承を持っていて、それを望んでいません。

誰かが別のデザインを提案できますか?

どんな助けでも大歓迎です!

0 投票する
7 に答える
2798 参照

java - Javaでホモグラフィックメソッドを使用してインターフェースを実装する方法は?

英語では、同形異義語のペアは、スペルが同じで意味が異なる 2 つの単語です。

ソフトウェア エンジニアリングでは、ホモグラフィック手法のペアとは、名前が同じで要件が異なる 2 つの手法です。質問をできるだけ明確にするために、不自然な例を見てみましょう。

どうすれば実装できI12ますか? C#にはこれを行う方法がありますが、Java にはありません。したがって、唯一の回避策はハックです。リフレクション/バイトコードのトリック/その他を最も確実に使用するにはどうすればよいですか(つまり、完璧なソリューションである必要はありません。最適なソリューションが必要なだけです)。


合法的にリバース エンジニアリングできない既存のクローズド ソースの大規模なレガシー コードには、型のパラメーターが必要であり、その両方をパラメーターとして持つコードとパラメーターとして持つコードI12に委任することに注意してください。したがって、基本的には、いつ として機能する必要があるか、いつとして機能する必要があるかを知るのインスタンスを作成する必要があります。これは、直接の呼び出し元の実行時にバイトコードを調べることで実行できると思います。これは単純なコードであるため、呼び出し側でリフレクションが使用されていないと想定できます。問題は、 の作者がJavaが両方のインターフェースからマージされるとは予想していなかったことです。何も呼ばないI12I1I2I12I1I2I12fI12.f(明らかに、作成者が実際に を呼び出すコードを書いていれば、I12.fそれを販売する前に問題に気付いていただろう)。

私が実際に探しているのはこの質問に対する答えであり、変更できないコードを再構築する方法ではないことに注意してください。可能な限り最良のヒューリスティック、または存在する場合は正確な解決策を探しています。有効な例については、グレイの回答を参照してください(より堅牢なソリューションがあると確信しています)。


以下は、2 つのインターフェース内でのホモグラフィック メソッドの問題がどのように発生するかを示す具体的な例です。そして、ここに別の具体的な例があります:

次の 6 つの単純なクラス/インターフェイスがあります。それは、劇場とそこに出演するアーティストを取り巻くビジネスに似ています。簡単かつ具体的にするために、それらはすべて異なる人々によって作成されたと仮定しましょう。

Set集合論のように集合を表す:

HRDepartmentSet従業員を表すために使用します。洗練されたプロセスを使用して、どの従業員を雇用/解雇するかを解読します。

従業員のユニバースは、Setおそらく雇用主に応募した従業員になります。したがって、complementそのセットで が呼び出されると、既存の従業員はすべて解雇され、以前に応募した他の従業員はすべて雇用されます。

Artistミュージシャンや俳優などのアーティストを表します。アーティストにはエゴがあります。この自尊心は、他の人が彼を褒めると増加する可能性があります。

TheaterパフォーマンスをArtist行い、Artist補完される可能性があります。劇場の観客は、公演の合間にアーティストを判断できます。パフォーマーのエゴが高ければ高いほど、聴衆は を好きになる可能性が高くなりますがArtist、エゴが特定のポイントを超えると、アーティストは聴衆から否定的に見られます。

ArtistSetは単純にArtistSet:

TheaterManagerショーを実行します。劇場の観客がアーティストを否定的に判断した場合、劇場は人事部門に相談し、人事部門はアーティストを解雇したり、新しい人を雇ったりします。

を実装しようとすると、問題が明らかになりますArtistSet。両方のスーパーインターフェイスcomplementが、何か他のことを行うように指定しているためcomplement、何らかの方法で、同じクラス内に同じシグネチャを持つ 2 つのメソッドを実装する必要があります。Artist.complementの同形異義語ですSet.complement

0 投票する
3 に答える
177 参照

c++ - このダイヤモンド継承 UB は MinGW のバグですか?

私はこのようなコードを持っています。Windows 8 の MSVC 2012 x64、Ubuntu 12.10 および 13.04 の g++ 4.7 および Clang++ 3.2 (x86 と x64 の両方) で期待どおりに動作します。ただし、疑問符のある行は、MinGW 4.7 x86 でコンパイルすると未定義の動作を示します。または MinGW 4.8 x64(申し訳ありませんが、私はそう思っていました)。

デバッガーの出力は、その時点で TargetClass の vtable へのリンクに問題があることを示しています。ブレークポイントを配置すると、TargetClass::operator string() が不適切に逆参照されたオブジェクトでロードされていることがわかります。ただし、明示的な dynamic_cast を配置すると、正しい出力が得られます。

何がこの問題を引き起こす可能性があるのだろうか。MinGW のバグであれば、C++ のコア コンセプトの 1 つを壊すため、おそらくすぐに解決されるでしょう。

0 投票する
1 に答える
383 参照

multiple-inheritance - Coqの致命的な死のダイヤモンド

かなり単純な型階層を作成しようとしています。最小限の作業例を次に示します。

その最後の強制により、次の警告が生成されます。

実際、R12to R0(またはSortclass) からの型強制は 2 つの異なるパスを取ることができます。そして、Coqが一般的なケースでこれを許可しない理由を理解しています. だって...どれが使われるの?

ただし、この場合、両方のパスによる強制がまったく同じR1_0 (R12_1 r12)であることを示すことができます。R2_0 (R12_2 r12)しかし、それでも、次の一見有効な公理を追加することはできません。

質問:では、これで問題ないことを Coq に納得させる方法はありますか?

0 投票する
2 に答える
1014 参照

c++ - C++ ダイアモンド オブ デス

わかりましたので、すべてのクラスを完全に制御できる場合に死のダイヤモンドの継承の問題を解決する方法を理解していますが、両方から継承する最後のクラスのみを制御できる場合はどうなるでしょうか。

また、B と C を編集する方法がなく、D のみを編集できます。これを行う簡単な方法はありますか?

0 投票する
1 に答える
117 参照

c++ - c++ 仮想/非仮想 Diamond 継承

C++ で次のコードがあるとします。

誰かが理由を説明できますかC* c = new C(); 1 23 と 16 をこの順序で出力しますか? どの順序で印刷するかをどのように決定しますか? B1非仮想が最後に呼び出されることはわかっていますがA()、最初に呼び出されるのはなぜですか? 事前に助けと説明をありがとう。