問題タブ [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 に答える
2469 参照

c++ - 派生クラスが仮想関数をオーバーライドしないのに、なぜvptrが必要なのですか?

ここで、クラスで定義された関数fnのシグニチャは、関数名は同じですが、クラスで定義されたbase関数のシグニチャとは異なります。したがって、クラスで定義された関数はクラス関数を非表示にします。したがって、fnのクラス バージョンを呼び出しで呼び出すことはできません。それは結構です。fn()derderbasefn()derp->fn(i)

私のポイントは、なぜsizeofクラスなのbaseか、それともVTABLEポインターを使用しないのかということですder。ここでのVTABLEポインターの要件は何ですか?4

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

c++ - vptr を実装するための代替スキーム?

この質問は、C++ 言語自体に関するものではなく (つまり、標準に関するものではありません)、コンパイラを呼び出して仮想関数の代替スキームを実装する方法に関するものです。

仮想関数を実装するための一般的なスキームは、ポインターのテーブルへのポインターを使用することです。

同様に、Cは次のようになります

最初のメンバーは通常、仮想関数のリストなどへのポインターです (アプリケーションが制御できないメモリー内の領域)。そしてほとんどの場合、これはメンバーなどを考慮する前にポインターのサイズを消費することになります。したがって、32 ビットのアドレッシング スキームでは、約 4 バイトなどです。アプリケーションで 40k ポリモーフィック オブジェクトのリストを作成した場合、これは約 40k x 4 バイト = メンバー変数などの前に 160k バイト。また、これがたまたま C++ コンパイルの中で最も高速で一般的な実装であることもわかっています。

これは複数の継承によって複雑になることを私は知っています (特に仮想クラス、つまりダイヤモンド構造体など)。

同じことを行う別の方法は、最初の変数を vptrs のテーブルへのインデックス ID として持つことです (以下の C と同等)。

アプリケーション内のクラスの総数が 255 未満の場合 (可能なすべてのテンプレートのインスタンス化などを含む)、char はインデックスを保持するのに十分であり、アプリケーション内のすべてのポリモーフィック クラスのサイズを縮小します (アライメントの問題は除外しています)。など)。

私の質問は、GNU C++、LLVM、または他のコンパイラにこれを行うためのスイッチはありますか?? またはポリモーフィック オブジェクトのサイズを縮小しますか?

編集:指摘されたアライメントの問題について理解しています。また、これが 64 ビット システム (64 ビット vptr を想定) で、各ポリモーフィック オブジェクト メンバーのコストが約 8 バイトである場合、vptr のコストはメモリの 50% です。これは主に大量に作成された小さなポリモーフィックに関連しているため、アプリケーション全体ではないにしても、少なくとも特定の仮想オブジェクトに対してこのスキームが可能かどうか疑問に思っています。

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

c++ - C ++ /コンパイル:vptrのサイズを設定することは可能ですか(グローバルvtable + 2バイトインデックス)

最近、C++の仮想化によるメモリオーバーヘッドについての質問を投稿しました。答えにより、vtableとvptrがどのように機能するかを理解できます。私の問題は次のとおりです。私はスーパーコンピューターで作業しています。何十億ものオブジェクトがあり、その結果、仮想性によるメモリのオーバーヘッドを気にする必要があります。いくつかの対策の後、仮想関数でクラスを使用すると、各派生オブジェクトには8バイトのvptrがあります。これはまったく無視できません。

Intelicpcまたはg++に、vptrの代わりに調整可能な精度で「グローバル」vtablesおよびインデックスを使用するための構成/オプション/パラメーターがあるかどうか疑問に思います。そのようなことで、数十億のオブジェクトに対して8バイトのvptrの代わりに2バイトのインデックス(unsigned short int)を使用できるようになるためです(そしてメモリオーバーヘッドが大幅に削減されます)。コンパイルオプションを使用してそれ(またはそのようなもの)を行う方法はありますか?

どうもありがとうございます。

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

c++ - C++: 仮想ポインターのプロトタイプ

これがどこかに文書化されているかどうかはわかりません。仮想関数の場合、各クラスは、仮想テーブルと呼ばれる関数ポインターの配列を指す vptr を保持します。vptr のプロトタイプを知りたいです。たとえば、クラスが次のように宣言されている場合、

現在、クラス A の vtable に 2 つの関数ポインタがあります。1 つの vptr で異なるプロトタイプの 2 つの定義を実行するにはどうすればよいでしょうか?

私の理解が間違っている場合はお知らせください。

どうも!ラフル。

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

c++ - サブオブジェクトにVPTRが存在する

仮想デストラクタを含むクラス「base」があり、VTableとそれに対応するVTPRがあり、そこから派生したクラスがあります。

派生クラスも仮想であるため、独自のVPTRがありますが、VPTRを含む基本クラスのサブオブジェクトもあるため、クラス「der」のサイズを8バイトにしないでください。クラス'der'のVPTRのサイズ+クラス'base'のサブオブジェクトのVPTRのサイズ?(sizeof(void *)= 4バイトの場合)。

したがって、基本的に私の質問は次のとおりです。クラス「base」のサブオブジェクトが「der」で作成された場合、別の新しいVPTRがありますか?もしそうなら、なぜ'der'のサイズを計算しているときにそのサイズが追加されないのですか?

誰かがこれを明確にしてくれませんか。

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

c++ - オブジェクト内の仮想関数テーブル ポインタの場所

私が理解しているようvirtualに、オブジェクト内の関数ポインター テーブルの場所はコンパイラに依存します。
このポインターをオブジェクトの先頭と末尾、またはその逆に配置することの長所/短所はありますか?

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

java - コンストラクターでの仮想メソッドの呼び出し: Java と C++ の違い

Java の場合:

これは出力されます

ただし、C++ では結果が異なります。

( C++ コードについては、 http://www.parashift.com/c++-faq-lite/calling-virtuals-from-ctors.htmlを参照してください)

Java と C++ のこのような違いの原因は何ですか? vtableが初期化された時ですか?

編集: Java と C++ のメカニズムは理解しています。私が知りたいのは、この設計上の決定の背後にある洞察です。

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

c++ - パラメータ化されたコンストラクタのみを持つクラスで初期化されるvptr(仮想ポインタ)はどこにありますか?

私がこのようなクラスを持っているとしましょう

VPTRは、コンストラクターの先頭で初期化されます。ただし、この場合、デフォルトのコンストラクターはなく、パラメーター化されたコンストラクターは2つだけです。VPTRはどこで初期化されますか?

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

c++ - vptr が静的でないのはなぜですか?

1 つ以上の仮想関数を含むすべてのクラスには、関連付けられた Vtable があります。vptr と呼ばれる void ポインターは、その vtable を指します。そのクラスのすべてのオブジェクトには、同じ Vtable を指す vptr が含まれています。では、なぜ vptr static ではないのでしょうか? vptr をオブジェクトに関連付ける代わりに、クラスに関連付けてみませんか?

ここに画像の説明を入力

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

c++ - 特性を入力してプライマリ基本クラスを識別します

少なくとも1つの仮想関数を持つクラスBaseがあり、これから単独で継承するクラスDerivedが(uintptr_t)derived - (uintptr_t)static_cast<Base*>(derived)ある場合、Derivedは標準レイアウトではありませんが、(Itanium ABIによって)ゼロであることが保証されます。ただし、一般的なケースでは、これは必ずしも正しいとは限りません(例:多重継承)。

あるクラスが別のクラスのプライマリ基本クラスであるかどうかを検出するために使用できるトレイトを作成することは可能ですか?

Itanium ABIの便利なセクション:

http://refspecs.linux-foundation.org/cxxabi-1.83.html

一次基本クラス

動的クラスの場合、オフセット0で仮想ポインターを共有する一意の基本クラス(存在する場合)。これは、存在する場合、最初の(直接基本クラスの順序で)非仮想動的基本クラスです。

動的クラス

仮想テーブルポインタを必要とするクラス(それまたはそのベースに1つ以上の仮想メンバー関数または仮想ベースクラスがあるため)。