1

私は非常に奇妙な問題を抱えています:

基本クラスの 1 つである IEventlistener() を使用します。これは、他の多くのクラスによって実装されます。ほとんどの場合、システムは機能します。しかし今、非常に奇妙な問題が発生しました。

クラス (CGUIService) がインターフェイスを実装すると、1 つのメソッド (VGetListenerName) が期待どおりに機能し、コールスタックをチェックすると、もう 1 つのメソッド (VHandleMessage) が純粋な呼び出しを取得し、理由がわかりません -.- (vtable が何らかの形で取得されるようです)上書きまたは範囲外 ...)

VHandleMessage を呼び出す前に変数を確認できるように、スクリーンショットを作成しました。これはもちろん、デバッグ アサーション R6025 につながります。これは、実装されたメソッドが IEventlistener() の vtable に入力されていないためです。

ハイレゾ: www.fantasyhaze.com/cb/Error_purecall.png www.fantasyhaze.com/cb/Error_purecall.png

誰かが私にヒントをくれることを願っています:)

編集1.)

もう少し説明するために、同じプロセスを示す新しいスクリーンショットを作成しましたが、純粋ではなく、実装されている 2 つの仮想関数を追加しました (時間の理由により、時間がありません)。インターフェイスを使用する各クラスですべてのメソッドを再度実装します)

紫色のものは新しいものです。赤色のものは機能しないものです。オレンジ色のものは以前に存在し、機能し、現在も機能している方法です。

左側で、VGetListenerName、VHandleEvent1、VHandleEvent2 が機能し (デバッグポイント + 現在の位置)、これら 3 つが vtable にあることがわかりますが、重要なもの (赤) ではありません。

高解像度: www.fantasyhaze.com/cb/Error_purecall2.png vtable 問題 2

編集2.)

解決:

主な問題は、CGUIService が IBase から継承することでした。サービスにアクセスするには、各サービスを格納する Service Locator を使用しました。そのため、Instance Getters Service::GetServiceInstance() で static_cast を実行し、サービスを IBase として格納するために static_cast も実行されました。しかし、IEventListener は IBase に実装されておらず、サービスは IEventListener なしで IBase にキャストバックされ、vtable は適切ではありませんでした。現在、IBase は IEventListener を実装しており、static_cast が IEventListener を正しくキャストするため、機能します :)

ヒントの人のためのThx :)

4

3 に答える 3

2

多くの場合、純粋仮想呼び出しは、既に破棄されたオブジェクトで仮想関数を呼び出すことによって発生します。オブジェクトが破棄されると、すべての基底クラスのデストラクタが仮想テーブル ポインタをクラスの仮想テーブルに設定します。関数が純粋仮想であり、実装がない場合、純粋仮想コール ハンドラ アドレスが仮想テーブルに配置されます。

于 2011-01-26T08:30:27.077 に答える
1

1 つのスクリーンショットから判断するのは難しいですが、あなたが提供した情報から、私の最初の推測はダングリング ポインターであると推測されます。おそらく、既に破棄されたオブジェクトで仮想メソッドを呼び出そうとしているのではないでしょうか? もう 1 つの可能性は、オブジェクトがまだ完全に構築されていないことですが、複数のスレッドで何らかの競合状態が必要になる可能性が高いため、可能性は高くありません。

この可能性とその他の可能性は、C++ で純粋仮想関数呼び出しを引き起こす原因は?にリストされています。かなり徹底的に。

于 2011-01-26T08:30:51.510 に答える
0

purecall は、何らかの理由で、インターフェイスを実装するクラスが実装するインターフェイスよりも仮想関数が少ないことを意味します。これは、次の場合によく発生します。

  • インターフェイスにメソッドを追加します
  • 呼び出し元で新しいメソッドを使用する
  • 呼び出し元を再コンパイルしますが、実装を再コンパイルしないでください (または、実装を再コンパイルして、それに対して再リンクするのを忘れてください)。

したがって、ビルドプロセスの問題である可能性があります。呼び出し元が依存するすべてのものを再コンパイルしたことを確認し、必要に応じて呼び出し元を再リンクします。

于 2011-01-26T08:29:38.837 に答える