問題タブ [vptr]

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

c++ - クラスが仮想メソッドを宣言し、コンパイラがvptrを使用する必要がない場合はありますか?

オブジェクトの型が仮想メソッドを持つクラスであっても、コンパイラーがインスタンス化されたオブジェクトにvptrを割り当てる必要がない最適化の可能性があるかどうか疑問に思いました。

たとえば、次のことを考慮してください。

この例では、コンパイラはコンパイル時にpFooのタイプを確実に認識しているため、pFooにvptrを使用する必要はありません。コンパイラがvptrの使用を回避できるもっと興味深いケースはありますか?

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

c++ - 既存のすべてのvtableのリストを取得する

私のアプリケーションにはかなりの数のvoidポインタがあります(これは歴史的な理由によるもので、アプリケーションは元々純粋なCで書かれていました)。私のモジュールの1つでは、voidポインターが、既知の基本クラスから継承できるクラスのインスタンスを指していることを知っていますが、100%確信することはできません。したがって、voidポインタでdynamic_castを実行すると、問題が発生する可能性があります。おそらく、voidポインターはプレーン構造体を指していることさえあります(したがって、構造体にvptrはありません)。

void-pointerが指しているメモリの最初の4バイトを調べて、これが有効なvtableのアドレスであるかどうかを確認したいと思います。これはプラットフォームであり、コンパイラバージョン固有である可能性もありますが、アプリケーションを前進させ、限られた期間(たとえば、3年)ですべてのボイドポインタを取り除くのに役立つ可能性があります。

アプリケーション内のすべてのvtableのリストを取得する方法、またはポインターが有効なvtableを指しているかどうか、およびvtableを指しているそのインスタンスが既知の基本クラスを継承しているかどうかを確認する方法はありますか?

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

c++ - 複数の仮想継承と型キャストのための仮想テーブルと仮想ポインタ

vptr とメモリ内のオブジェクトの表現について少し混乱しています。問題をよりよく理解するのに役立つことを願っています。

  1. Binherits fromAと、両方が virtual functions を定義することを検討してくださいf()。私が学んだことから、メモリ内のクラス B のオブジェクトの表現は次のように[ vptr | A | B ] なります。また、オブジェクトをからにキャストしても、オブジェクトの最後の部分を無視する以外は何もしないことも理解しました。本当ですか?この振る舞いは間違っていませんか?型のオブジェクトがではなく メソッドを実行するようにします。vtblvptrB::f()BABAA::f()B::f()

  2. クラスの数vtablesとしてシステムにいくつかありますか?

  3. vtable2 つ以上のクラスを継承する of クラスはどのようになりますか? C のオブジェクトはメモリ上でどのように表現されるでしょうか?

  4. 質問 3 と同じですが、仮想継承があります。

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

c++ - クラスのオブジェクト(単一/多重継承を使用)にはいくつのvptrがありますか?

clas(child)がbase1とbase2を複数継承する基本クラスを持つ単一の継承を持つオブジェクトに通常必要なvptrの数。オブジェクトが単一の継承と多重継承のカップルを持っている場合に、オブジェクトが提供したvptrの数を識別するための戦略は何ですか。標準ではvptrsについて指定されていませんが、実装が仮想関数の実装をどのように行うかを知りたいだけです。

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

c++ - C++オブジェクトがVPTrを失うのはなぜですか

プログラムのコアダンプの1つをデバッグしているときに、多形である含まれているオブジェクトがVPTrを失い、NULLを指していることがわかるシナリオに遭遇しました。

オブジェクトがVPTrを失った場合のシナリオは何でしょうか。

よろしくお願いします、ブリジェッシュ

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

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.

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

c++ - クラスの v-table はいつ作成されますか?

仮想関数呼び出しの解決を実装する方法は C++ 標準の一部ではなく、vptr または v-table についても何も述べていないことはわかっていますが、ここでこの質問をさせてください。

v-table は、コンパイラが仮想関数呼び出し解決を実装するために使用する一般的な手法であると聞いたことがあります。これについての私の理解は、クラスごと、プロセスごとに仮想テーブルのみが必要であるということです。

私が疑問に思っているのは、クラスの v テーブルが作成されるのはいつですか?
特定のタイプのクラス (v-table が必要) がプロセス空間で初めて作成されたときですか?
そのプロセス空間でその後作成されたそのタイプの他のすべてのオブジェクトは、すでに作成されている v-table を参照していますか?
この v-table はいつ削除されますか?

これがあまりにも主観的またはディスカッションタイプの質問である場合は申し訳ありませんが、これらの質問はしばらく頭に残り、ここで質問しても問題ないと思います.

0 投票する
11 に答える
5662 参照

c++ - 代替の仮想関数呼び出しの実装?

C++ は、仮想メカニズムによる動的バインディングをサポートしています。しかし、私が理解しているように、仮想メカニズムはコンパイラの実装の詳細であり、標準は特定のシナリオで発生するべき動作を指定しているだけです。ほとんどのコンパイラは、仮想テーブルと仮想ポインタを介して仮想メカニズムを実装します。これは、仮想ポインタとテーブルの実装の詳細に関するものではありません。私の質問は次のとおりです。

  1. 仮想ポインタと仮想テーブルメカニズム以外の方法で仮想関数の動的ディスパッチを実装するコンパイラはありますか? 私が見た限りでは、ほとんど (G++、Microsoft Visual Studio を読む) は、仮想テーブル、ポインター メカニズムを介して実装しています。実際には、他のコンパイラの実装はまったくありますか?
  2. sizeof仮想関数だけを持つクラスの は、そのthisコンパイラのポインタ (vptr 内部)のサイズになります。仮想ポインターと TBL メカニズム自体がコンパイラーの実装であることを考えると、上記のステートメントは常に正しいのでしょうか?
0 投票する
3 に答える
332 参照

c++ - なぜVPTRが必要なのですか?

また、非仮想関数にも同じ方法を使用しないのはなぜですか?

つまり、なぜそのように仮想関数を使用するのでしょうか。それらを非仮想的なものとして使用し、それらをオーバーライドすることはできませんか?

そして、この方法で時間やスペースなどを節約できるのであれば、非仮想関数に同じ方法を使用してみませんか?つまり、特定のクラスに対して1つの関数テーブルがあることは理にかなっています。

とにかく、事前のおかげで、私は少し混乱しています。

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

c++ - 多重継承でvptrを理解していますか?

本の効果的なc ++のステートメントを理解しようとしています。以下は、多重継承の継承図です。

ここに画像の説明を入力

ここに画像の説明を入力

現在、この本には、vptr には各クラスに個別のメモリが必要であると書かれています。また、次のステートメントを作成します

上の図の奇妙な点は、4 つのクラスが関係しているにもかかわらず vptr が 3 つしかないことです。実装は、必要に応じて 4 つの vptr を自由に生成できますが、3 つあれば十分です (B と D が vptr を共有できることがわかります)。ほとんどの実装では、この機会を利用して、コンパイラが生成するオーバーヘッドを削減します。

vptr の各クラスに個別のメモリが必要な理由がわかりませんでした。vptr は、継承タイプが何であれ、基本クラスから継承されることを理解していました。継承されたvptrを使用して結果のメモリ構造を示していると仮定すると、どのようにステートメントを作成できますか

B と D は vptr を共有できます

誰かが多重継承の vptr について少し明確にしてくれませんか?

  • クラスごとに個別の vptr が必要ですか?
  • また、上記が当てはまる場合、B と D が vptr を共有できるのはなぜですか?