2

C ++でメンバー関数アドレスを出力する方法で、変数の型キャストに(void *&)を使用し、(void *)を使用しようとしましたが、問題があります。私が求めているのは、型キャスト時のC ++の(void *)変数と(void *&)変数の違いは何ですか。リンク内のコードスニペット:

void TestClass::PrintMyFuncAddress(void)
{
  void (TestClass::* ptrtofn)() = &TestClass::MyFunc;
  cout << (void*&)ptrtofn<< endl;
}
4

2 に答える 2

2

void*キャストは、 の値を void へのポインタ型の値に変換しようとしますptrtofun。C++ は、ポインターからメンバー関数へのそのような変換を提供しません。そのためvoid*、何か問題があります (おそらくコンパイルされません)。

void*&キャストは参照を作成します。その参照先は、 object が占有sizeof(void*)する最初のバイトから始まるメモリの最初のバイトptrtofnです。ptrtofunは型も互換型も持たずvoid*、 と同じサイズである必要さえありませんvoid*。したがって、参照を使用すると未定義の動作が発生します (厳密なエイリアシングの違反です) が、コンパイラは問題をキャッチする必要はありません。

メンバーへのポインター関数を移植可能に出力する唯一の方法は、sizeof(ptrtofun)から始まるバイトを出力すること(unsigned char*)(&ptrtofun)です。これらのバイトをどのように表現するかを自分で正確に決めることができますが (16 進数は明らかな選択です)、結果が必ずしも のコードのメモリ内のアドレスではないことに注意しくださいTestClass::MyFunc。メンバー関数へのポインターは、単にそのようには機能しません。たとえば、仮想関数へのポインターを許可する必要があるためです。これは、呼び出されるオブジェクトの動的な型に応じて異なるコードを呼び出します。

于 2012-11-02T17:40:01.607 に答える
0

void *& にキャストすると、void * タイプへの参照が得られます。これは、左辺値として使用できることを意味します。void * は、式で使用できる r 値を提供します。しかし、これは実際にはあなたの質問には関係ありません。

メンバー関数へのポインターをデータへのポインターまたは関数へのポインターに変換することはできません。これらは基本的に異なるタイプです。通常 sizeof(ptr_to_member_function) != sizeof(void*) (または sizeof(void (*)() については))。

メンバー関数へのポインターには、その関数のコードの先頭へのポインターが含まれているとは限りません。仮想機能の VTBL へのオフセットが含まれる場合があります。

私は確信が持てませんが、C++ 標準ではこれらの変換が許可されていません。

于 2012-11-02T17:43:02.310 に答える