typeidを介してXがYから派生したかどうかを確認します
質問
iポインターをlongに変換する必要がある(SendMessage()) そして、変数が反対側で正しいかどうかを安全にチェックしたいです。したがって、dynamic_castを実行することを考えていましたが、仮想ではないクラスでは機能しません。次に、typeidを実行することを考えましたが、派生変数をベースとして渡すまで動作します。
実行時にポインターが予期したものであるかどうかを確認する方法はありますか? typeidを使用して、ポインターが特定のベースから派生した型であるかどうかを確認する方法はありますか?
解決
お持ちのすべてがlong
である場合、実際にできることはあまりありません。任意の数値が有効なメモリアドレスを表すかどうかを判断する一般的な方法はありません。また、有効なメモリアドレスであることがわかっていても、ポインタが指すもののタイプを判別する方法はありません。アドレスが<=>にキャストされる前にモノの実際のタイプがわからない場合は、キャストする予定のタイプに<=>をキャストしても安全かどうかわからないそれに。
メッセージの送信者から有効な値が送信されたことを信頼する必要があります。あなたができる最善のことは、偽の値を受け取ったときにあなた自身のプログラムへの結果を減らすためにいくつかの予防措置を取ることです。
他のヒント
SendMessage()
を参照すると、MS Windowsがプラットフォームであるように聞こえ、ポインターの使用規則(Windows)を読むことをお勧めします。このような状況でMicrosoftが提供するPtrToLong
およびPtrToUlong
関数の詳細を説明します。
typeidは使用できません。有効なポインターではなくガベージを取得すると、アクセス違反が発生するため、チェックは無意味です。
すべきことは、SendMessageと、メッセージを処理するコードを単一のタイプセーフインターフェイスにラップすることです。これにより、予期しないものをSendMessageに渡すことができなくなり、受信側でチェックを行う必要がなくなります。
C ++型システムはコンパイル時に機能します。 longにポインターをキャストすると、すべての型情報が失われます。 longはメモリ内のビットと同じです。オブジェクトを指していたことを特定する方法はありません。
PTLib( http://sourceforge.net/projects/opalvoip/ )はPCLASSINFOを使用しますクラス間の関係を定義するマクロ。これにより、IsDescendantやGetClassなどの機能が提供されます。
おそらく同様のものを実装できます。
dynamic_castは、仮想メソッドテーブルの署名をチェックすることで機能します。仮想メソッドがない場合、VMTがないため、dynamic_castは機能しません。ただし、VMTがない場合は、ポイントされているオブジェクトについてまったく知識がありません。
最善の策は、ポインターが少なくとも1つの仮想メソッドを持つクラスへのポインターであることを要求することです(たとえそれがダミーであっても)。ダイナミックキャストが機能します。
質問の内容がまだわかりません。
- ロングとバックへのキャストで同じ値が得られるかどうかを確認できるかどうかは、変数の型の安全なチェック
<!> quot;ポインターを使用するためのルール<!> quot; MS-Siteがリンクしている他のAnswerer、キャストする正しいタイプはUINT_PTR
です。したがって、UINT_PTR v = reinterpret_cast<UINT_PTR>(ptr);
を実行して整数型にキャストし、逆の操作を行ってポインターに再度キャストします。 C ++標準では、元の値が復元されることが保証されています。 (その説明については、上記のリンクを参照してください)。ちなみにMicrosoftのサイトはまた、WPARAMとLPARAMはプラットフォームに応じてサイズが変わると言っています。そのため、その変数v
およびSendMessage
を使用できます。 - 反対側で(あるポインタータイプに変換された)ポインターが特定のオブジェクトを指しているかどうかを確認する方法であれば、答えはできませんです。どのポインタータイプが送信に使用されたかは明らかでないため、ポインターが指す動的タイプが受信側で確認できません。ポインターが送信者側で持っているタイプがわかっている場合、最初はチェックは不要です。
Windowsでは、MFCは、指定されたポインターが有効なメモリ位置を指しているかどうかを確認する方法を提供します(これは、segfaultのトラップによって行われます)。関数名は覚えていませんが、あります。それでも、ポイントされたメモリの内容が有効であることを保証しません。それでも無効なVMTがあり、コードがクラッシュする可能性があります。もちろん、自分でセグメンテーション違反をトラップすることができます( MSナレッジを参照ベース)
何かが型に属しているかどうかを確認するには、最初に基本クラスが必要です。基本クラス<!> quot; virtual <!> quot;のデストラクタを作成すると、すべての派生クラスにVMTが含まれます。
VMTをどうしても避けなければならない場合、MS Windowsイベントのイベントタイプなど、何を扱っているかを示す何らかの種類の説明文が必要です。