問題タブ [double-dispatch]

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 投票する
1 に答える
599 参照

oop - マルチディスパッチとマルチメソッド

それらは何ですか、それらの間の違いは何ですか?

ウィキペディアのような多くの情報源は、それらは同じものであると主張していますが、この質問のsbiのように、他の情報源は明示的に反対のことを言っています:

最初:「ビジターパターンは、C++でのダブルディスパッチをシミュレートする方法です。」これは、えーと、完全には正しくありません。実際、ダブルディスパッチはマルチディスパッチの1つの形式であり、C ++で(欠落している)マルチメソッドをシミュレートする方法です。

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

c++ - C++ 二重ディスパッチの問題

これは、私が以前に尋ねた問題のパート 2 です: C++ でポリモーフィック メンバーのオーバーロードを行うことは可能ですか?

Wiki の例を使用して、この例を作成しました。 http://en.wikipedia.org/wiki/Double_dispatch

私の問題は、コンパイルされたコードが vtable を検索せず、継承されたクラスの代わりに常にベースを使用することです。これが私のコードです:

ただし、出力は常に次のようになります。

この謎についての助けは大歓迎です。

0 投票する
5 に答える
7162 参照

java - Java でポリモーフィックにディスパッチする

以下では、EventHandler が EventA をある方法で処理し、EventB を別の方法で処理し、他のすべてのイベント (EventC、EventD) をさらに別の方法で処理するようにします。EventReceiver は Event への参照のみを受け取り、EventHandler.handle() を呼び出します。もちろん、常に呼び出されるバージョンは EventHandler.handle(Event event) です。

instanceOf を使用せずに、(おそらく EventHandler またはジェネリックの別のメソッドを介して) 適切なハンドル メソッドにポリモーフィックにディスパッチする方法はありますか?

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

c++ - 二重ディスパッチで「仮想関数を非表示」という警告が表示されるのはなぜですか?

型が共通の基本クラスから派生した 2 つのオブジェクト間の相互作用を実装したいと考えています。デフォルトの相互作用があり、同じタイプのオブジェクトが相互作用すると特定のことが起こる場合があります。これは、次の二重ディスパッチ スキームを使用して実装されます。

残念ながら、このコードに関してまったく異なる質問が 2 つあります。

  1. これは合理的なアプローチだと思いますか?何か違うことを提案しますか?
  2. 最初の 2 つのメソッドを省略すると、最後の 2 つのメソッドがメソッドを隠してBいるというコンパイラの警告とエラーが表示されます。何故ですか?ポインターをポインターにキャストするべきではありませんか?BAA*B*

更新:追加することがわかりました

エラーと警告が消えますが、なぜこれが必要なのですか?

更新 2 : これはここできちんと説明されています: http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.9、ありがとう。私の最初の質問はどうですか?このアプローチに関するコメントはありますか?

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

c++ - 完全な階層を知らずに二重ディスパッチ

C++で次のことを実装したいと思います。

これらのタイプのいずれかのオブジェクトのペアを取る関数を呼び出す機能を備えた、単一のクラスの一連の子クラスが必要です。混合型または基本型に対して呼び出される一般的な実装と、同じ派生型の 2 つのオブジェクトが引数として使用される場合に呼び出される特殊な実装があるはずです。

私の知る限り、これは二重ディスパッチの古典的なアプリケーションです。ただし、次の制約があります。

既存のクラスから新しいクラスを派生させ、既存のクラスを変更せずに、これらの新しいクラスに新しいペア関数を追加することが可能でなければなりません。たとえば、外部ライブラリ..

前回の質問で提案したアプローチには誤りがあり、そこで提案された解決策は、基本クラスが作成された時点で既知の型に対してのみ機能します。

これを実装する方法について何か提案はありますか? それは可能ですか?

更新: コードは 1000 語以上を語ります。次のアプローチが機能します。

Bただし、実装する際には の知識が必要Aです。より良い方法はありますか?

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

c++ - std::shared_ptr と double コールバック

継承階層内のオブジェクトに std::shared_ptrs を使用しているロジックがあります。ある時点で、これらのオブジェクトを実際の型に応じて処理する必要があるため、二重ディスパッチを使用しています (つまり、基本クラスでメソッドを呼び出し、次に、実際の型を持つ別のオブジェクトのメソッドを呼び出します。例を参照してください)。 GoF の訪問者パターン)。

この時点で、オブジェクトへの参照を正しい型またはコピーで渡すことができます。いくつかの理由から、コピーは論外です。呼び出しは shared_ptr が存在するスコープより下のスコープで発生するため、参照は通常は問題ありません。したがって、この呼び出しが発生している間は破棄されません。ただし、一部のサブタイプでは、オブジェクトを STL コンテナーに格納する必要があるため、オブジェクトが破棄されないようにする必要があります。明らかに、裸のポインターまたは新しい shared_ptr はここでは機能しないため、これが呼び出された shared_ptr への参照を取得する必要があります。

現在、私は次のことを行っています。実際のコンストラクターではなく、名前付きコンストラクターを使用してオブジェクトを作成します。これにより、オブジェクト内に weak_ptr が設定され、オブジェクトを使用するための shared_ptr が提供されます。二重のコールバックが発生すると、weak_ptr から新しい shared_ptr を取得し、これをコンテナーに格納するので、オブジェクトは破棄されません。ただし、これにより、構築のロジックが非常に醜くなります。

これを行うより良い方法はありますか?

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

c++ - テンプレートを使用して、物理衝突を二重にディスパッチしようとしています

物理衝突システムの関数の接続をコンパイラに構築させたいと考えています。私はテスト衝突機能を持っています:

次に、コライダー オブジェクトを使用して衝突オブジェクトを保持します。

エフェクト関数に一定レベルの間接性を追加しました

私が行き着きたいと思っているのは、正しい関数シグネチャを持ち、ヒットしない型を必要としない任意のオブジェクトで関数を呼び出す方法です。

壁にぶつかる壁の機能を持たせたくないことに注意してください。発生する必要がある相互作用の関数のみを作成または提供したい。VictimEffect は派生関数を「認識」しないため、これが機能しないことはわかっています。

テンプレートパラメーターが使用されているすべての場所で、テンプレートパラメーターを指定せずにディスパッチしたい。衝突可能とは別に衝突可能効果を構築し、それを衝突可能オブジェクトに一般的に与えたいと考えています。衝突できるもののコレクションごとに異なる衝突可能なオブジェクトを持ちたくありません。基本的に欲しい

ここには間接的な層がもっと必要ですが、それが見えません。コンパイル時にすべての情報が利用可能であるため、それが可能であることはわかっています。動的なポリモーフィック ソリューションは必要ありません。

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

更新 私がやろうとしているのは、独自の最新の (Andrei の本のように) ゲーム ライブラリを構築することです。これまでのところ、私はほとんどの関係を解決してきましたが、これには困惑しています. これは時間的に重要な問題ではなく、結果が重要な問題です。私は何年もの間ゲームの仕事をしてきましたが、私が取り組んできたゲーム エンジンはどれも好きではありません。これは、使いやすく、拡張しやすいことを目的としています。コンソール コンパイラがそれほどひどくなくなったので、どのプラットフォームでも動作します。

これは、私が書きたいことの簡単な例です。

すべての Physics は WIP であり、私が望むところには行き着いていませんが、それは達成されつつあります。System object は、Windows とプラットフォーム固有のレンダラーを初期化します。この場合はopenGLです。コンソール アプリとしてコンパイルされますが、すべての Windows コンポーネントを作成します。私は人々に main() と winmain() を扱いたくありませんでした。物理学を除いて、継承はありません。シーンをシステムに取り込むと、3 つのレンダー コールが 1 つに置き換えられます。少し前に書いたものを、Gary Powell と Martin Weiser の View テンプレート ライブラリと組み合わせて使用​​する予定です。

私はそれを正しく見ていないことを知っています。訪問者は、私のアプローチを変えるのに役立ちます。

それが私がやろうとしていることです。

更新 2 OK。これまでのコメントと回答からインスピレーションを得て、ここに行きましたが、まだ終わっていません。

それを使用するには、これを行います

万能は正しかった。ベースを渡すことで型情報を失っていました。今のベースは、どうでもいいことをキャッチするためだけにあります。

私のコンテナでは、タイプリストを使用してコンテナに追加されたすべてのタイプを収集し、それを使用して情報を処理するタイプ固有のコンテナを宣言できると思います。ただし、関数オブジェクトを渡す方が簡単な通常のイテレータを取り出すことができないという問題があります。

おそらく、C++ 0X はその新しい未知の型変数に役立つでしょう。(名前は忘れました)。

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

c++ - std::shared_ptrのベクトルを保存するここで、Fooはテンプレート化されたクラスです

いくつかの関数に必要なタイプを変更したいので、テンプレートを作成した基本クラスがありますが、これらのテンプレート化された基本クラスから派生したいと思います。これらのクラスのベクトルを保存したいと思います。私のアイデアは、階層内のすべての上にテンプレート化されていない基本クラスを作成し、ダブルディスパッチを使用してタイプを把握することでした。私はこれを「正しい方法」で行っていますか?

シナリオのコードスニペットは次のとおりです。

//およびFoo、Fooから派生した多くのクラス

その後、別のクラスで

これが「最善の」方法かどうかはわかりません。dynamic_castingを使用できますが、それは汚い感じがします。それで、これは状況に対する固溶体ですか?アドバイスしてください(例に明白な構文エラーを残さなかったと思います)

(編集は削除されました、私の側の愚かなエラーでした)

0 投票する
4 に答える
209 参照

c++ - 抽象基本クラスXが与えられた場合、別のテンプレートクラスDを作成する方法ここで、TはXから派生したクラスのタイプですか?

またはクラスMessage&のいずれかを参照するオブジェクトを受け入れられるようにしたい。オブジェクトの基になるタイプに基づいて、またはを作成できるようにしたい。たとえば、以下を参照してください。Message1Message2MessageWithData<Message1>MessageWithData<Message2>Message&

messageWithDataクラスには、基本的にMessageから継承されたメソッドが含まれており、そのタイプに基づいて、動的にダブルディスパッチしてハンドラーに戻すことができます。これまでの私の最善の解決策は、データをメッセージタイプから分離し、動的ディスパッチチェーン全体に渡すことでしたが、メッセージタイプに可変データ。

(私が多かれ少なかれフォローしている方法は、http://jogear.net/dynamic-double-dispatch-and-templatesからのものです)