問題タブ [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.

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

c++ - 抽象クラス(Qt)の「vtableへの未定義の参照」

QCExpressionNode式をツリー構造に解析するためのライブラリを作成しており、基本クラスとして抽象型を使用しています。次のようになります。

サブクラス(、、、など)で機能するいくつかのテスト(QtCreatorの別のプロジェクト)をコンパイルするQCConstantNodeQCVariableNodeQCBinaryOperatorNodeリンカーはQCExpressionNodeの「vtableへの未定義の参照」エラーを表示します。私は何が間違っているのですか?

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

c++ - vtableへの未定義の参照

afporoillsメモリ管理モジュールでデータを見つけるのに役立つクラスがあります。(なぜそんな奇妙な名前がわからないのか聞かないでください)

私は取得し続けます

[リンカーエラー]`vtableforafporoills`への未定義の参照

しかし、vtableが何であるかわかりません!!! 使用したことがないのに、なぜエラーが発生するのですか?

そのエラーを取り除けないと、そのクラスを書き続けることができないので、私を助けてください。

testまた、メソッドをチューリング完全にするために何をする必要がありますか?

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

c++ - VTableとポリモーフィズム

VTableについてたくさん読んだ後でも、未回答の質問が1つあります。

次のクラスを考えると:

および次のテスト:

私はこの出力を取得します:

私の質問は次のとおりです。sがCircle::drawをどのようにアドレス指定するかは知っていますが、変数b = 5をどのように知ることができますか?このテストが示すように、sにはこの情報がありません。ここで何が欠けていますか?

ありがとう!

OKみんな。迅速な回答をありがとう...

あなたの回答から、Circle :: draw()(* this)はCircleタイプであることがわかりました。わかった。私の質問はこれに変わりました。私はsをShape*タイプにしたいだけだったので、つまり、プログラムではShape品質だけが必要でした。次の4バイト(Circleのb変数)がコンパイラによって何らかの形で取得される可能性はありますか?その場合、明らかにCircle :: draw()は期待どおりに機能しません。

そうでない場合、コンパイラは、sの「終了」の後にこれらの次の4バイトが必要であることをどのように認識しますか?

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

c++ - SEGFAULT - C++ 純粋仮想上。なんで?

Cコードを介して純粋仮想基本クラスポインタを として渡していvoid *ます。

C++ で基本クラスを逆参照すると、デバッガーはそのすべてのメンバーにアクセスできます。ただし、純粋仮想関数にアクセスしようとすると、SEGFAULT/アクセス違反が発生します。「0xc でメモリにアクセスできません」というメッセージがデバッガーに表示されます (純粋な仮想関数にアクセスしようとすると)。

コンストラクターが戻る前に関数が呼び出されている可能性がありますが、これは問題になりますか? 他に何を探すべきですか?他のすべての変数は無傷のようです。

コード:

更新: コードは部分的に機能しており、オブジェクトが削除された可能性があります。読み取りハンドラー (それ自体を削除できます) を実行してから、チェックせずに書き込みハンドラーを実行するため...おそらくそれが原因です。


答え

最終更新: Keith のコメントが正しかったことを明確にしたいと思います。オブジェクトを削除していて、削除後にアクセスしようとしました。非常に単純な間違い!delete this;トリッキーな落とし穴です。すべてのコメントをありがとう。

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

c++ - 特定の仮想関数のvtableオフセットを検出します(Visual C ++を使用)

特定の仮想関数のvtableオフセットを検査できますか?

なんで?意図しないバイナリ互換性の破損を検出できるようにしたいと思います(バイナリ互換性の意味については、 http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2Bを参照してください)。

「/d1reportSingleClassLayout」(http://blogs.msdn.com/b/vcblog/archive/2007/05/17/diagnosing-hidden-odr-violations-in-visual-)の文書化されていないサポートされていない手法を知っています。 c-and-fixing-lnk2022.aspx)であり、この手法を使用する予定ですが、可能であれば、いくつかの単純なコンパイル時または実行時のチェックも使用したいと思います。

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

c++ - セグメンテーション違反を呼び出す仮想関数

仮想機能にアクセスしようとすると、常にセグメンテーション エラーが発生します。コードは基本的に次のようになります。

仮想機能について知っているほとんどすべてを試しましたが、うまくいきません。実際にはより大きなプログラムの一部であるため、問題がある可能性がありますが、仮想関数を削除するか、仮想化を停止するとすぐに機能します。何か案は?

また、vtable を調べるツールや方法はありますか?

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

c++ - C++ コピー コンストラクター - 小さいが重要な違い

ここで何が起こっているのか理解できませんでした。非常に奇妙だと思いました。その理由を理解した後、答えを共有することは誰かの時間にとって価値があると思いました。

したがって、次の単純なコードが与えられます。

次の 2 つのテストで 2 つの異なる答えが得られるのはなぜですか。

ま、仮想の仕組みはついつい知ってしまったので、どちらのテストでも同じ結果が得られると思いました(Circleを印刷)。これはtest2で発生することですが、 test1ではそうではありません。

その理由を理解するために、バックグラウンドで実際に何が起こっているかを書きました。

Test1: 1. プログラムは「Circle()」という行を実行します。1.1 Shape のデフォルト コンストラクタが呼び出されます (Circle は Shape から派生しているため)。1.2 Circle のデフォルト コンストラクタが呼び出されます。

  1. プログラムはアクション「Shape shape =」を実行します。これは実際に Shape のコピー コンストラクターを呼び出します。*ここで、コピー コンストラクターは Circle の非表示フィールドである _vptr をコピーしないことに注意してください。a の値をコピーして (*this) を返すだけです。これが Circle を印刷しない本当の理由です。

ここで、別の質問があります。test1 を実行すると、次の出力が得 られました。

コピー コンストラクターのシグネチャがShape(const Shape& s) の場合、この出力によると、シェイプを実際にShapeとして作成する前に、コピー コンストラクターの呼び出しがあります。これはどのように起こりますか?

Test2: 1. クラス Circle の新しいインスタンスがヒープ上に構築されています。(行new Circleが実行されます) 2. ヒープ上のメモリ内のそのアドレスへのポインターが返され、ポインターの形状に配置されます。このアドレスの最初の 4 バイトには、Circle の仮想テーブルへのポインターがあります。これが、test1 が test2 と異なる理由です。

テストの違いは、test1 がスタック上に Circle を構築し、test2 がヒープ上に Circle を構築するという事実とは何の関係もないことを理解することが重要です。いや、実は関係あるんです。しかし、本当の理由は、コピー コンストラクターが _vptr をコピーしないことです。

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

c++ - 仮想メソッドがある場合、vtableは作成されますか?

このような非常に単純なクラスを作成すると、次のようになります。

(仮想デストラクタなし)コンパイラはvtableを作成しますか?または、最新のコンパイラは、このケース(コピーアンドペーストが不適切な場合があります)を認識し、そのようなクラスの仮想テーブルを追加しないほど賢いですか?

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

c++ - 複数の継承を処理するときにポインタを揃える方法は?

具象クラス A と抽象クラス B があるとします。

A と B の両方から継承し、B を実装する具体的な C を考えてみましょう。

今、私は署名である関数を定義しますvoid foo(B* b);

これは私のコードです。B へのすべてのポインターは A と B の両方であると想定できます。foo の定義では、A へのポインターを取得する方法は? 厄介だが有効なトリックは、次のようにポインターを後方に揃えることです。

Cにはスーパータイプがなく、実際にはCに似た多くのクラスがあり、それらはAとBのみであることに注意してください。私のロジックとこの設計サンプルの両方に自由に質問してください。ただし、質問はポインターの配置のみに関するものです.

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 を共有できるのはなぜですか?