問題タブ [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 投票する
2 に答える
383 参照

c++ - 二重ディスパッチによる C++ ポリモーフィック循環依存関係

だから、私は循環依存に大きな問題を抱えています。私の Square.h と Circle.h クラスは両方とも Shape.h を継承し、2 つの間の衝突を検出しようとするために二重ディスパッチを使用します。私のクラスは現在、次のような方法でセットアップされています

シェイプ.h

Square.h

Circle.h

基本的に、私は次のようなことができるようになりたいと思っています

しかし、これをコンパイルしようとすると、いくつかのエラーが発生します。明らかに「Circle.h」を含めて、Square.h 内で実行されない循環ループが発生します。誰かがこの問題の良い解決策を提案できますか?

明らかに、2 つの正方形と円と正方形の間の衝突検出は異なるため、何らかの方法でこれらのメソッドをオーバーロードする必要があります。これは良い解決策だと思いましたが、何か指針はありますか?

エラー (これらのコンパイル エラーは同じか、Square.cpp と Shape.cpp です):

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

c# - .Net 4.0 既存の「if」条件と「is」演算子をリファクタリングするために最適化されたコード

次のC#コードがあります。正常に動作します。しかし、メソッドはis 演算子を使用することで複数の条件GetDestination()で雑然としています。if

.Net 4.0 (またはそれ以降) では、これらの「if」条件を回避する最善の方法は何ですか?

編集: ロールはビジネス モデルの一部であり、宛先は純粋にそのビジネス モデルを使用する特定のアプリケーションの成果物です。

コード

参考文献

  1. さまざまなタイプのデリゲートを持つ Dictionary<T,Delegate>: よりクリーンな非文字列メソッド名?
  2. Jon Skeet: リフレクションを飛ばしてデリゲートを探る
  3. if-else vs. スイッチ vs. デリゲートの辞書
  4. デリゲートまたはスイッチを使用した辞書?
  5. C# での式とデリゲート
0 投票する
2 に答える
164 参照

c++ - ダブルディスパッチ無限ループ

二重ディスパッチを使用して、別の (A) のサブクラスである2 つのクラス ( B、 )の 2 つのオブジェクト間の距離を取得しています。のメソッドは純粋仮想であるべきだCと思いますが、他の場所のテストで使用されるため、インスタンス化可能でなければならないので、純粋仮想にすることはできませんよね?class Aclass A

Distance(A *a)もう 1 つのことは、基本クラスの の定義で無限ループが発生する場合があるため、ダブル ディスパッチを適切に使用しているかどうかわからないことです。

にはclass A、次のメソッドがあります。

class B

class C

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

c++ - 衝突検出システムのクラス構造に関するアドバイス

C++ は、オブジェクト指向を使用する言語として私が初めて広く使用した言語であり、そのため、私はまだその考えに少し慣れていません。Go (真の OOP システムではなくインターフェイスを使用) から C++ に取り組んでいたゲーム ライブラリを移植しようとしています。

ポイント、バウンディング、ライン、ポリゴンの 4 つのタイプを使用する衝突システムがあります。私がやりたいのは、これらすべてを「コライダー」クラスに抽象化できるようにし、2 つのコライダー オブジェクトを取り、衝突をテストできる関数を持たせることです。次のようになります。

当初は、別のタイプの衝突をテストする各衝突タイプのメソッド (つまり、メソッド OnPoint、OnBounding、OnLine、および OnPolygon) を用意し、「Collider」をこれらすべてのメソッドを必要とする仮想クラスにすることができると考えていましたが、それから、コンパイルのためにクラスが互いに依存するようになるため、C++では不可能であることに気付きました(そうですか?)。

他に何ができるのか少し途方に暮れています。私のデザインのアイデアは夢物語ですか?

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

c++ - 動的キャストなしで派生クラス属性をコピーする手段

外部の 2 つの派生クラス間で特定の属性をコピーする効率的な方法 (ポリモーフィズムを使用) を見つけようとしています。基本クラスから派生した一連のデータ クラスがありますDataClassADataClassAこれらのデータ クラスを、参照を入力および出力パラメーターとして受け取る別のフィルター クラスで操作したいと考えています。フィルタは に共通する必要な操作を実行しますが、DataClassAクラス固有の属性を入力クラスから出力クラスに伝播したいと考えています。検討:

私の問題は明らかにcopyAttributes()、入力と出力の両方の派生クラスの型を知る必要があることに依存していることです (必ずしも同じである必要はありません)。ただし、フィルターは基本クラスへの参照のみを処理しますDataClassA。私の反射神経は単純に を導入することですdynamic_castが、手を叩かれるリスクがあります (およびその他の悪影響が考えられます)。これを行った場合、親クラスのcopyAttributesを呼び出した派生クラスごとにメソッドを作成し、それを使用してオブジェクトが同じ型かどうかを確認します。copyAttributesdynamic_castcopyFrom

この問題について私が見つけた最も類似した投稿は、ここVirtual functions and polymorphismでした。私の主な質問は次のとおりです。1) 私の提案した dynamic_cast の使用は不適切ですか?; copyAttributes2)もしそうなら、どうすればこれを別の方法で実装できますか? ビジターデザインパターンの使用についての言及がありましたが、それがどのように見えるかはわかりません.

これは、Visualization Toolkit (VTK) が行うことの単純なバージョンの一種で、さまざまなデータ クラスで動作するフィルターのクラスを使用しているという意味です。興味深いことに、データ型の正しいダウンキャストのために直接比較できるクラスと親クラスの文字列名を含むマクロを含めることで、RTTI を処理します。

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

design-patterns - 訪問者がどのように横断するかを選択する訪問者パターン

私が理解しているように、訪問者パターンの典型的な仕様では、どのようにトラバースするかを決定するのは訪問されたオブジェクトであり、一般に、それらは 1 つのトラバース順序のみをサポートします。(たとえば、ここまたはここを参照してください。)

訪問者がオブジェクト階層をどのようにトラバースするかを決定する場所である、ダブルディスパッチの同じ使用の名前はありますか? 私のアプリケーションでは、ドキュメント モデル タイプの非常に異種のコレクションが、エクスポート操作などのために訪問者にプッシュしています。ただし、さまざまなプロセッサ (訪問者) がすべて、たとえば幅優先の順序でトラバースする必要があると言うのは硬直しているように思えます。それらの一部は、モデルのサブセットのみに関係する場合や、モデルの一部を特殊な順序で処理する必要がある場合があります。

訪問者パターンの名前を非標準的な方法で使用して、他の開発者を混乱させることを懸念しています。私が提案しているものに名前はありますか?

また、訪問者にトラバーサルを制御させない理由があるかどうかも尋ねます。これは、通常の訪問者の定式化に、私が見逃している知恵がある場合に備えてです。関連する可能性がある場合、アプリケーションは Java です。

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

c++ - テンプレート クラスに沿った非仮想インターフェイスを使用したダウンキャスト

有限要素コードを実装しています。

問題の説明

有限要素法では、積分器と補間器が必要です。積分器は、四角形、三角形などの幾何学的オブジェクトで数値積分を実行するオブジェクトです。積分器は、幾何学的オブジェクト内に複数の積分点または横座標を配置し、補間器を使用して次の値を近似します。これらの統合点での関数。

たとえば、四角形のオブジェクトは、4 つの積分点を使用する積分器を使用できます。

ここで、@ は積分点の位置を表します。補間器は、* で表されるコーナー ノードの値を使用して、これらの積分点での関数の値を概算します。@ の各値は、すべての * の値の一種の平均であると考えることができます。

ポリモーフィズムの概要

次の図は、便宜上、この質問で使用されるさまざまなクラス間の接続を示しています。

各幾何学的形状には異なる座標系があるため、積分器と横座標は次のようになります。

Integrator.hpp

すべての自然座標横軸の基底クラス。

横座標.hpp

四角形の横座標は、ξ と η の自然座標に作用します。

Abscissa_Quad.hpp

三角形の横座標は、ζ1、ζ2、および ζ3 自然座標に作用します。

Abscissa_Tria.hpp

インテグレーターの実装は、次のように統合されます。

Integrator.cpp

ここまでは順調ですね。私の補間クラスをお見せしましょう。

Interpolator.hpp

補間器から、すべての幾何学的形状のクラスを派生させます。Interpolator_Template クラスをベースとして使用していることにお気付きかもしれません。詳細は後ほど説明しますので、今は無視してください。このクラスには、すべての四角形に共通の関数が含まれています。

Interpolator_Quad.hpp

この派生クラスは、この質問の最初に描かれた四角形に対応します。これが導出される理由は、より多くの補間ノードを持つ四角形が存在する可能性があるためです。このクラスは QUAD_04 要素 (4 つの補間ノードを持つ四角形) を実装しますが、有限要素には QUAD_08、QUAD_09 などもあります。

Interpolator_Quad_04.hpp

Interpolator_Quad_04.cpp

前に説明し損ねた Interpolator_Template クラスに戻りましょう。コードのある時点で、Abscissa * から Abscissa_Quad * オブジェクトへのダウンキャストを実行します。テンプレート クラスを非仮想インターフェイス パターンと組み合わせて使用​​することで、これを実現しました。

Interpolator_Template.hpp

Interpolator_Template.cpp

このコードにはエラーが含まれているに違いありません。要点を理解するために必要だと思われるものだけをコピーして貼り付け、変更を加えなければならなかったからです。しかし、私の考えが正しく伝わることを願っています。

通常、ダウンキャスティングはコードのにおいがすることを知っているので、有限要素のすべての幾何学的形状の積分器と補間器の実装を始める前に、あなたの意見を聞きたいと思いました。

私の以前の試み

これは、私が実装した最後のデザイン パターンです。以下に、私が試みた他のデザインについて説明します。ただし、このセクションを読み飛ばしてもかまいません。

  • インターポレーターではなくインテグレーターが派生するダブル ディスパッチ デザイン パターン (具体的にはビジター パターン)。たとえば、Interpolator_Quad_04 ではなく Integrator_Quad_04 がありました。Integrator_Quad_04 には Abscissa_Quad がメンバー変数としてありました。これは、横座標が派生されなくなったためです。

    次に、インターポレーターはインテグレーター クラスのビジターになり、その _abscissae メンバー変数にアクセスします。この設計には従わないことにしました。これは、形状ではなく操作に基づいて補間器を実装する必要があったからです。

    /li>
  • 複数のディスパッチで何かをやってみましたが、すべての形状に必要な関数の数がかなり速く増えました。

  • ダブルディスパッチ+テンプレートの複数のバリエーション。

  • ここで使用している現在のデザインパターンを見つけました:

    オブジェクト指向設計問題、リスコフ置換原理

結論

コードから推測できるように、私は C++11 を使用してコンパイルしています。

積分器と補間器を単純に 1 つのクラスに結合しない理由を不思議に思われるかもしれません。その答えは、積分器が四辺形の部分領域で動作する可能性があるからです。たとえば、四角形の内部に架空の三角形を導入し、三角形の内部に積分点を配置することもできますが、それでも四角形の補間を使用して三角形の点内の解を近似します。もちろん、三角形と四角形の座標間のマッピングを実装する必要がありますが、それはまた別の機会にします。

ダウンキャストがこの問題の悪い解決策ではないと思うかどうか、または何かが足りないかどうかを知りたいです。おそらく、この問題を修正する設計パターンの知識がないか、ポリモーフィズム アーキテクチャが正しくない可能性があります。

フィードバックをお待ちしております。ありがとう!

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

java - Java による双方向の拡張可能な階層

私の質問は、可能な限り拡張可能な方法で、さまざまなメッセージに対してさまざまな動作を実装することです。私は訪問者のパターンを認識しており、二重ディスパッチを認識していますが、私を満足させる解決策を見つけられないようです(少なくともJavaの制限内ではありません)。

私の状況は次のとおりです。

私はメッセージの階層を持っています:

メッセージ階層

およびルーター インターフェイスの階層。それぞれが独自のメッセージ タイプのルート メソッドを定義します。

ルーター インターフェイス階層

私はこれに似たものを実装したいと思います:

実装

特定のメッセージをルーティングする機能を追加および削除したり、特定のメッセージのルーティング戦略を簡単に変更したりできます。

問題は、やりたくないメッセージをスイッチキャストしないと、インターフェースのそれぞれの機能を選択できないことです。

オーバーロードを選択するJavaにつながります<runtime message-type>.process(Router)

これは、実行時にそれぞれのルーター オブジェクトに対して呼び出されます。そのため、コンパイル時に process() への正しい呼び出しを選択できないようです。その逆もできないので、comp.route(msg)

に解決され<dynamic router-type>.route(MessageBase)ます。

CompositeRouter から適切なメソッドを選択するビジターを作成することもできますが、そのためには、事前にすべての MessageTypes に対して定義されたそれぞれの route-Methods を使用してビジター インターフェイスを定義する必要があります。新しい DerivedMessage を追加するたびに、訪問者を書き換える必要があります。

Message と Router の両方が拡張可能になるようにこれを実装する方法はありますか、それとも現在の Java 機能では絶望的ですか?

編集1:

Router私が言及するのを忘れていたのは、 -hierarchyとほとんど同じである他の 4 つまたは 5 つの状況があるということです。そのため、ランタイム コストが心配なので、メソッド ルックアップのリフレクションは避けたいと思います。

コメントへの対応:

  1. @bot の提案に関する @aruisdante の仮定は正しいです。route(MessageBase) をオーバーライドすると、MessageBase のランタイム タイプが失われるため、オーバーライドできません。

  2. @aruisdanteと@geceo:私はそれができることを知っています-これは「スイッチキャスティング」で意味したことです(MessageBaseにはMessageTypeフィールドがあります)-しかし、コードには11の実際のメッセージクラスと〜6の場所が必要です、したがって、それはメンテナンスの面だけでなく、実装の面でも大きな苦痛になるでしょう。