問題タブ [vtable]
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.
virtual-functions - std::string を返す仮想関数の「add esp,4」はありません
私は DynObj を見ていて、vftablesで自分の実験を行うことにしました。私は Visual Studio 2010 で作業しており、std::string を返す仮想関数を使用してオブジェクトをインスタンス化するコンソール メインを作成しました。
main のテスト コードは、オブジェクトの vftable から取得したポインターを使用して、オブジェクトのパブリック仮想関数を呼び出そうとします。プリミティブ型を返す関数には問題がないことがわかりました。ただし、関数が std::string を返すと、コンパイラは有効なスタック ポップを挿入します (esp,4 を追加します)。これにより、後続のスタック チェック コードで例外がスローされます。
これは、グローバル空間で宣言された関数の標準であることに気付きました。しかし、クラス内の関数は ESP 修飾子のポスト コールを生成しません。
アセンブリと一緒にコードの本質は次のとおりです...
キャストされたポインターを介した仮想関数への最後の呼び出しの結果は次のようになります。
実行時チェックの失敗 #0 - ESP の値が関数呼び出しで適切に保存されませんでした。これは通常、ある呼び出し規約で宣言された関数を、別の呼び出し規約で宣言された関数ポインターで呼び出した結果です。
だから私の質問は次のとおりです。非プリミティブ型を返す仮想関数で適切な呼び出し規約を呼び出すにはどうすればよいですか?
ところで、00BE178B で中断し、次のステートメントを 00BE178E に設定すると、実行は問題なく完了します。
c++ - 仮想デストラクタを使用すると、非仮想関数が v-table ルックアップを行うようになりますか?
トピックが求めるものだけです。また、CRTP の通常の例で dtor が言及されていない理由も知りたいですvirtual
。
編集:みんな、CRTPの問題についても投稿してください、ありがとう。
c++ - Virtual dispatch implementation details
First of all, I want to make myself clear that I do understand that there is no notion of vtables and vptrs in the C++ standard. However I think that virtually all implementations implement the virtual dispatch mechanism in pretty much the same way (correct me if I am wrong, but this isn't the main question). Also, I believe I know how virtual functions work, that is, I can always tell which function will be called, I just need the implementation details.
Suppose someone asked me the following:
"You have base class B with virtual functions v1, v2, v3 and derived class D:B which overrides functions v1 and v3 and adds a virtual function v4. Explain how virtual dispatch works".
I would answer like this:
For each class with virtual functions(in this case B and D) we have a separate array of pointers-to-functions called vtable.
The vtable for B would contain
The vtable for D would contain
Now the class B contains a member pointer vptr. D naturally inherits it and therefore contains it too. In the constructor and destructor of B B sets vptr to point to B's vtable. In the constructor and destructor of D D sets it to point to D's vtable.
Any call to a virtual function f on an object x of polymorphic class X is interpreted as a call to x.vptr[f's position in vtables]
The questions are:
1. Do I have any errors in the above description?
2. How does the compiler know f's position in vtable (in detail, please)
3. Does this mean that if a class has two bases then it has two vptrs? What is happening in this case? (try to describe in a similar manner as I did, in as much detail as possible)
4. What's happening in a diamond hierarchy with A on top B,C in the middle and D at the bottom? (A is a virtual base class of B and C)
Thanks in advance.
c++ - インターフェイスのオーバーヘッド
Boost.Arrayのような単純なクラスがあります。テンプレートパラメータTとNは2つあります。Boost.Arrayの欠点の1つは、そのような配列を使用するすべてのメソッドが、パラメータN(TはOK)のテンプレートでなければならないことです。その結果、プログラム全体がテンプレートになる傾向があります。1つのアイデアは、T(ArrayInterfaceのようなもの)のみに依存するインターフェイス(純粋仮想関数のみを含む抽象クラス)を作成することです。これで、他のすべてのクラスはインターフェイスにのみアクセスするため、テンプレートパラメーターTのみが必要になります(Nとは対照的に、多かれ少なかれ常に知られています)。ここでの欠点は、インターフェイスが使用されている場合、仮想呼び出しのオーバーヘッド(インライン呼び出しの機会を逃す機会が増える)です。ここまでは事実だけです。
しかし、私の本当の問題はどこかにあります。Boost.Arrayをインターフェイスで拡張すると、Boost.Arrayの直接インスタンス化が遅くなります(重要な場合は、ファクター4)。インターフェイスを削除すると、Boost.Arrayは以前と同じように高速になります。ArrayInterfaceを介してメソッドが呼び出された場合、オーバーヘッドが発生することは理解しています。しかし、純粋仮想メソッドのみを含む追加のインターフェイスのみがあり、クラスが直接呼び出される場合、メソッドの呼び出しが遅くなる理由がわかりません。
GCC4.4.3とClang1.1は同じ動作を示します。
c++ - 仮想関数のアライメントを設定するには?
Linux から mingw とクロスコンパイルを使用して Win32 用のプラグインを開発しています。プラグインはアプリケーションによって正常にロードされ、アプリから com インターフェイスを取得しましたが、そこから関数を呼び出すことができません - アプリがクラッシュしました。これは、mingw のインターフェイス実装の vtable 配置が間違っているためだと思います (これは MSVS で完全に機能しました)。
どんな助けでも感謝します、ありがとう。
c++ - 代替の仮想関数呼び出しの実装?
C++ は、仮想メカニズムによる動的バインディングをサポートしています。しかし、私が理解しているように、仮想メカニズムはコンパイラの実装の詳細であり、標準は特定のシナリオで発生するべき動作を指定しているだけです。ほとんどのコンパイラは、仮想テーブルと仮想ポインタを介して仮想メカニズムを実装します。これは、仮想ポインタとテーブルの実装の詳細に関するものではありません。私の質問は次のとおりです。
- 仮想ポインタと仮想テーブルメカニズム以外の方法で仮想関数の動的ディスパッチを実装するコンパイラはありますか? 私が見た限りでは、ほとんど (G++、Microsoft Visual Studio を読む) は、仮想テーブル、ポインター メカニズムを介して実装しています。実際には、他のコンパイラの実装はまったくありますか?
sizeof
仮想関数だけを持つクラスの は、そのthis
コンパイラのポインタ (vptr 内部)のサイズになります。仮想ポインターと TBL メカニズム自体がコンパイラーの実装であることを考えると、上記のステートメントは常に正しいのでしょうか?
java - Javaインターフェイスは内部でどのように実装されていますか?(vtables?)
C++には多重継承があります。アセンブリレベルでの多重継承の実装は非常に複雑になる可能性がありますが、これが通常どのように行われるかについてはオンラインで適切な説明があります(vtables、ポインター修正、サンクなど)。
Javaには複数の実装継承はありませんが、複数のインターフェース継承があるため、クラスごとに1つのvtableを使用する単純な実装ではそれを実装できないと思います。Javaはどのようにインターフェースを内部的に実装しますか?
C ++とは異なり、JavaはJitでコンパイルされるため、コードの断片が異なれば最適化も異なり、JVMも異なると動作が異なる可能性があることを認識しています。それで、多くのJVMがこれに従ういくつかの一般的な戦略がありますか、または誰かが特定のJVMでの実装を知っていますか?
また、JVMは多くの場合、仮想化を解除してメソッド呼び出しをインライン化します。この場合、vtableまたは同等のものはまったく含まれないため、仮想/インターフェイスメソッド呼び出しを実装する実際のアセンブリシーケンスについて質問するのは意味がないかもしれませんが、ほとんどのJVMはまだいくつかを保持していると思いますすべてを非仮想化できなかった場合に使用するクラスの一般的な表現の一種。この仮定は間違っていますか?この表現はC++vtableのように見えますか?その場合、インターフェイスには個別のvtableがあり、これらはクラスvtableとどのようにリンクされていますか?もしそうなら、C ++のオブジェクトインスタンスのように、オブジェクトインスタンスは(クラス/インターフェイスvtablesへの)複数のvtableポインタを持つことができますか?同じオブジェクトへのクラスタイプとインターフェイスタイプの参照は常に同じバイナリ値を持ちますか、それともポインターの修正が必要なC ++のようにこれらが異なる可能性がありますか?
(参照:この質問はCLRについて同様の質問をします。このmsdnの記事には、今では時代遅れになっているかもしれませんが、良い説明があるようです。Javaに似たものは見つかりませんでした。)
編集:
- 「JavaクラスArrayListがListインターフェースを実装する」という意味ではなく、「GCCコンパイラが整数加算/関数呼び出しなどをどのように実装するか」という意味で「実装」を意味します。
- これがJVMバイトコードレベルでどのように機能するかを知っています。知りたいのは、クラスファイルのロードとバイトコードのコンパイルが完了した後にJVMによって生成されるコードとデータ構造の種類です。
c++ - 派生クラスの vtable が壊れていますか?
vtable の破損の問題を引き起こしているルートで助けが必要です (それが起こっているかどうかはわかりません)。これは、コードの非常に単純化されたバージョンです。
CDerived のインスタンスを作成し、派生クラスの仮想関数 (derived_virtual_fn2 など) を呼び出すと、別の関数 (derived_virtual_fn1) が呼び出されます。
base_virtual_fnx の呼び出しに問題はありません。
これは、ヒープ上に作成されたオブジェクトでのみ発生し、ローカル オブジェクトでは発生しません。
これらのクラスは共有ライブラリにあります。Linux (SLES 10) で gcc 3.4.2 を使用しています。このコードのいずれにも pragma pack ディレクティブはなく、C と C++ コードが混在しています (extern c が使用されています)。ここで何が問題になる可能性がありますか?
他にもたくさんのコード(実行可能ファイル、ライブラリ)があることを忘れていました
c++ - 継承とポリモーフィズムの低レベルの詳細
この質問は私の頭の周りに浮かぶ大きな疑問の1つであり、言葉で説明するのも難しいです。明白な場合もあれば、クラックするのが難しい場合もあるので、質問は次のようになります::
Q1。b_ptrは派生オブジェクトを指していますが、どのVTABLEにアクセスし、どのようにアクセスしますか?b_ptr-> function4()はコンパイルエラーを出します。または、b_ptrが派生VTABLEの基本クラスVTABLEのサイズまでしかアクセスできないということですか?
Q2。Derivedのメモリレイアウトは(Base、Derived)でなければならないので、BaseクラスのVTABLEもDerivedクラスのメモリレイアウトに含まれていますか?
Q3。基本クラスVtableのfunction1とfunction2は基本クラスの実装を指し、派生クラスのfunction2は基本クラスのfunction2を指しているので、基本クラスにVTABLEが本当に必要ですか?(これは私が今までに尋ねることができる最もばかげた質問かもしれませんが、それでも私は現在の状態でこれについて疑問があり、答えはQ1の答えに関連している必要があります:))
コメントしてください。
しばらくお待ちいただきますようお願いいたします。
c++ - マトリックス = *((fxMatrix*)&d3dMatrix); //悪の?
使ってきました
かなり長い間。画面が真っ暗になり、机の上でバケツのフラストレーションが溜まるまでは問題なく動作していました。
fxMatrix には 4 つの fxVectors が含まれています。fxVector は以前は 16 バイトでしたが、突然 20 になりました。これは、vTable を追加した fxStreamable を継承したためです。
したがって、1 つの解決策はもちろん、fxStreamable を継承せず、常に 16 バイトである必要があり、それ以上であってはならないというコメントを残すことです。
別の解決策は、変換関数を作成し、行列を完全にコピーすることです。これにより、より安全になりますが、パフォーマンスに影響します。これが一番いい考えだと思います。
もう 1 つの解決策は、まったく変換せずに D3DXMATRIX に固執することですが、これではエンジンに一貫性がなくなり、個人的にはこの考えが本当に嫌いです。
あなたの意見は何ですか?