1

アドレスを含む整数型を実際のポインタ型に変換する必要があります。次のようにreinterpret_castを使用できます。

MyClass *mc1 = reinterpret_cast<MyClass*>(the_integer);

ただし、これは、問題のアドレスが実際にMyClassオブジェクトを保持しているかどうかを確認するための実行時チェックを実行しません。最初にvoid*に変換し(reinterpret_castを使用)、次に結果にdynamic_castを使用することに利点があるかどうかを知りたいです。このような:

void *p = reinterpret_cast<void*>(the_integer);
MyClass *mc1 = dynamic_cast<MyClass*>(p);
assert(mc1 != NULL);

2番目の方法を使用することに利点はありますか?

4

8 に答える 8

2

型チェックdynamic_castは、さまざまなC++実装によってさまざまな方法で実装されます。特定の実装に対する回答が必要な場合は、使用している実装について言及する必要があります。一般的な質問に答える唯一の方法は、ISO標準C++を参照することです。

私が標準を読んだことdynamic_castによると、voidポインタを呼び出すことは違法です。

dynamic_cast<T>(v)

「Tがポインタ型の場合、vは完全なクラス型へのポインタの右辺値でなければなりません」

(ISO C ++標準の5.2.7.2から)。voidは完全なクラスタイプではないため、式は不正です。

興味深いことに、キャストの型はvoidポインタにすることができます。

void * foo = dynamic_cast<void *>(some_pointer);

この場合、dynamic_cast常に成功し、結果の値は、が指す最も派生したオブジェクトへのポインターになりますv

于 2009-12-02T10:42:12.837 に答える
2

いいえ、そうすることに特別な利点はありません。使用した瞬間reinterpret_cast、すべての賭けは無効になります。キャストが有効であることを確認するのはあなた次第です。

于 2009-12-02T10:26:34.660 に答える
2

実際には重大な利点はありません。void *がポリモーフィックオブジェクトへのポインタではないものを指している場合、すぐに未定義の動作(通常はアクセス違反)に遭遇します。

于 2009-12-02T10:26:49.417 に答える
1

安全な方法は、すべてのライブMyClassオブジェクトの記録を保持することです。このレコードをに保持std::set<void*>することをお勧めします。これは、要素を簡単に追加、削除、およびテストできることを意味します。

それらをsとして格納する理由は、整数からvoid*整列されていないポインタを作成するような厄介なリスクを冒さないためです。MyClass*

于 2009-12-02T10:35:38.807 に答える
0
  • まず第一に、への「再解釈」intvoid *悪い考えです。sizeof(int)が4でsizeof(void *)8(64xシステム)の場合、形式が正しくありません。

  • さらにdynamic_cast、ポリモーフィッククラスの場合にのみ有効です。

于 2009-12-02T10:42:46.423 に答える
0

the_integerが既知の基本クラス(少なくとも1つの仮想メンバーを持つ)を指していることが確実にわかっている場合は、実際には利点がある可能性があります。オブジェクトが特定の派生クラスであることを知っていることです。ただし、reinterpret_cast最初に基本クラスに移動してから、dynamic_cast:を実行する必要があります。

BaseClass* obj = reinterpret_cast<BaseClass*>(the_integer);
MyClass* myObj = dynamic_cast<BaseClass*>(obj);

void*inを使用することdynamic_castは無意味であり、単に間違っています。dynamic_castメモリ内の任意の場所に有効なオブジェクトがあるかどうかを確認するために使用することはできません。

非ポインタ型変数にアドレスを格納する場合にも注意が必要です。sizeof(void *)!= sizeof(int)であるアーキテクチャがあります(例:LP64)。

于 2009-12-02T10:48:38.310 に答える
0

オプション1は、唯一の(半)ポータブル/有効なオプションです。

オプション2:dynamic_castとして有効なC ++ではありません(voidは許可されていないため)。

実装レベルでは、宛先タイプに到達するためにソースタイプからのタイプ情報が必要です。void *からランタイムソースタイプ情報を取得する方法がない(または方法がない可能性がある)ため、これも無効です。

Dynamic_Castは、不明なタイプからではなく、タイプ階層を上下にカスケードするために使用されます。

補足として、型指定されていないポインタを格納するには、整数ではなくvoid*を使用する必要があります。intがポインタを格納するのに十分な大きさではない可能性があります。

于 2009-12-02T10:56:38.343 に答える
0

C ++でポインターを処理する最も安全な方法は、ポインターをタイプセーフで処理することです。これの意味は:

  • ポインタ以外にポインタを格納しないでください
  • ボイドポインタを避ける
  • 他のプロセスにポインタを渡さないでください
  • スレッド上でポインターを使用する場合は、weak_ptrを検討してください

この理由は次のとおりです。あなたがやろうとしていることは安全ではなく、安全でない(レガシー?)コードとやり取りしない限り回避することができます。この場合、MSaltersの答えを検討してください。ただし、それでも面倒であることに注意してください。

于 2009-12-02T10:58:57.187 に答える