問題タブ [dynamic-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.
ada - 動的ディスパッチ操作 (プリミティブ) の Ada カプセル化の背後にある理論的根拠
Ada では、タイプ T のプリミティブ操作は、T が定義されているパッケージでのみ定義できます。たとえば、Vehicules
パッケージがタグ付けされたレコードを定義Car
しBike
、両方とも共通のVehicle
抽象タグ付き型を継承している場合、クラス全体の型でディスパッチできるすべての操作をこのパッケージVehicle'Class
で定義する必要があります。Vehicles
プリミティブな操作を追加したくないとしましょう。ソース ファイルを編集する権限がないか、無関係な機能でパッケージを混乱させたくない場合です。
次に、 type で暗黙的にディスパッチする操作を他のパッケージで定義することはできませんVehicle'Class
。たとえば、車両をシリアル化する (ディスパッチ機能を使用してVehicles_XML
パッケージを定義するTo_Xml
) か、UI 要素として表示する (、、... ディスパッチ機能を使用してパッケージを定義する)Vehicles_GTK
などの場合があります。動的ディスパッチを実行する唯一の方法は、次のように記述することです。コードを明示的に; たとえば、内部:Get_Label
Get_Icon
Vechicle_XML
(そして、 で定義され、他の場所で使用されている Visitor パターンVehicles
はもちろん機能しますが、それでも同じ種類の明示的なディスパッチ コードが必要です。実際には、いいえ、しかしまだ書く定型コードがいくつかあります)
私の質問は次のとおりです。
T で動的にディスパッチする操作が T の定義パッケージで定義されるように制限されている理由はありますか?
これは意図的なものですか?これには何か歴史的な理由があるのでしょうか?
ありがとう
編集:
現在の回答に感謝します。基本的に、それは言語の実装(ルール/仮想テーブルの凍結)の問題のようです。
コンパイラは時間の経過とともに段階的に開発され、すべての機能が既存のツールにうまく適合するわけではないことに同意します。そのため、ディスパッチ オペレーターを独自のパッケージに分離することは、言語設計よりも既存の実装によって主に導かれる決定のようです。C++/Java ファミリ以外の言語は、そのような要件のない動的ディスパッチを提供します (たとえば、OCaml、Lisp (CLOS)。それが重要な場合、それらもコンパイル済み言語、またはより正確には、コンパイラが存在する言語です)。
この質問をしたとき、言語仕様レベルで、Ada 仕様のこの部分の背後にもっと根本的な理由があるかどうかを知りたかった (そうでなければ、仕様が動的ディスパッチの特定の実装を想定/強制することを本当に意味するのだろうか?)
理想的には、リファレンス マニュアルの理論的根拠やガイドラインセクション、言語のこの特定の部分に関するあらゆる種類のアーカイブされた議論など、信頼できる情報源を探しています。
c++ - Visual Studio で誤ったコール スタックをデバッグする方法
私は 3rd-Pary ライブラリの巨大なクラスを使用しています。関連するものの抜粋を次に示します。
アプリケーションがメモリ アクセス違反で壊れます。コール スタックの一番上の項目は の実装のコード行でSet_0xB0_0x23_IsoTableData
、2 番目の項目は次のようなコード行です。
デバッグ ビューでucData
は、値0x00000002
が であるため、実際には の実装を呼び出す代わりにSetTableSize
、コードに従って発生する必要があるように見えSet_0xB0_0x23_IsoTableData
ますが、指定されたパラメーターで呼び出されます。ポインターが有効でないため、明らかにエラーが発生します。
ここで何が起こるかを理解するために、私はすでに多くの時間を費やしてきました。Linux で GCC を使用して別のアプリケーション内で同じコードをコンパイルすると、そこで動作します。これは Visual Studio コンパイラのバグですか? このコードをコンパイルしても、警告は表示されません。
バグを再現するための最小限の作業例を作成することはできません-少なくとも、これが発生する理由を理解するまでは. SomeClass
ヘッダーにはかなりの数#ifdef
の s が含まれているため、最初に思ったのは、プリプロセッサの定義はSomeClass
、呼び出し元のコードをコンパイルするときと、含まれているモジュールをコンパイルするときでは異なるということでした。ただし、再確認したところ、定義は同じです。
だから私が聞きたいのは基本的に:
- 仮想メソッドの呼び出しが別の仮想メソッドの実装を呼び出すことができる条件は? (これは継承に関するものではありません。2 つのメソッドは同じクラスで定義されており、シグネチャを共有しておらず、可視性も異なります)
- このようなエラーをデバッグするにはどうすればよいですか? クラス インスタンスのディスパッチ ベクターを Visual Studio で表示することはできますか?
virtual-functions - Swift には動的ディスパッチと仮想メソッドがありますか?
C++/Java/C# のバックグラウンドから来て、Swift で仮想メソッドが表示されることを期待していましたが、Swift のドキュメントを読んでも、仮想メソッドについては言及されていません。
私は何が欠けていますか?
閲覧数が多いため、最新かつ非常に明確で詳細な回答に対して報酬を提供することにしました。
java - メソッドの動的ディスパッチとアクセス レベル
次のクラスを検討してください。
このコードの出力はA.bar()
、次にB.foo()
. public
メソッド foo() のアクセス レベルをからprivate
出力に変更すると、次のようになることに気付きましA.bar()
たA.foo()
。
なんで?
c++ - 動的ディスパッチの方法
討論
私が知っているすべての実装 (つまり、C++ コンパイラ) は、仮想ディスパッチ テーブルと仮想テーブル ポインター(つまり、既知のと) を使用して動的ディスパッチメカニズムを実装していることを認識しています。vtable
vptr
しかし、C++ 標準を調べると、C++ 標準では動的ディスパッチの実装方法が正確に規定されていないことがわかりました。これは、その動作が動的ディスパッチ動作に対する C++ 標準の要求に準拠していれば、ベンダーは動的ディスパッチに別の方法を使用できることを意味します。
質問
Q1.
vtable
s とvptr
s 以外に、動的ディスパッチを実装できる有効なメソッドはありますか?Q2. Q1が true の場合:実装者が動的ディスパッチを実装するために、他の有効なメソッドの代わりに
vtable
s およびsを使用することを決定した理由は何ですか?vptr
c++ - C++ で仮想関数テーブル ポインター (vfptr) を静的にできないのはなぜですか?
仮想関数テーブルがクラスのすべてのオブジェクトで同じである場合、そのテーブルへのポインター (vfptr) を静的にしてすべてのオブジェクトで共有できないのはなぜですか?
java - 暗黙的なペイロード タイプ ルーティングを使用する複数の @ServiceActivator メソッド
メソッドの引数タイプがペイロードタイプフィルターとして暗黙的に使用される複数のメソッド (またはそのようなもの)@MessageEndpoint
を持つ単一の Beanを定義するエレガントな方法はありますか?@ServiceActivator
アイデアは、引数の型でディスパッチすることにより、わずかに異なるさまざまなペイロード型を処理できる単一のサービス エンドポイントを持つことです。
私は、一致する引数の型を持つEventBus
任意の登録済みメソッドにイベント オブジェクトをディスパッチするGoogle Guava の を認識しています。@Subscribe
私は現在このアプローチを使用していますが、Spring Integrationでもこれが(ちょっと)可能かどうか疑問に思っていました。
c++ - コンパイラが実行時まで変数の真の型を判断できないのはなぜですか?
特定の条件下で、使用するメソッドの正確な実装をコンパイラが判断できないという話をよく耳にします。キツネの例では、子クラスでオーバーライドされたメソッド foo() を持つ親クラスの場合、コンパイラは実行時まで呼び出す foo() の実装を決定しないというシナリオを想像できます (人々が言うように)。したがって、動的ディスパッチ、vtables などの概念があります。
私の質問は、コンパイラが呼び出す正確な実装を決定できないのはなぜですか? 私は最近それについて考えるのをやめました、そして私はそれを正当化するために一生懸命努力してきました. おそらく、私が見逃していることが本当に明らかな何かがあるのでしょう (答えを聞いたとき、私はおそらく自分自身を蹴るでしょう)。それは単に外部環境によるものですか?もしそうなら、それはどのように正確に行われますか?
これは言語に依存する制限ですか、それとももっと基本的なものがありますか?
c++ - 共変の戻り値の型と型変換
s->duplicate()
タイプ のオブジェクトを返しますが、 でBox*
初期化するとエラーが発生しますBox*
。に変換されているようShape*
です。基本クラスのポインターに変換された場合、共変の戻り値の型を持つことのポイントは何ですか?:
エラー: