次の構文は何を意味しますか?C++構文の質問
typedef void* hMyClass; //typedef as a handle or reference
hMyClass f = &something;
const MyClass& foo = static_cast<MyClass&>(*f);
foo.bar();
次の構文は何を意味しますか?C++構文の質問
typedef void* hMyClass; //typedef as a handle or reference
hMyClass f = &something;
const MyClass& foo = static_cast<MyClass&>(*f);
foo.bar();
はstatic_castは、システムが実際に(動的キャストとは違って)あなたが別の参照型から変換されたとき、あなたは変換されているものは、実際にターゲット・タイプのインスタンスであることを確認してくださいしようとしないことを意味し。
したがって、hMyClassに含まれ、実際にMyClassのインスタンスが含まれていて、何かから来たものであることがわかり、予測できないものについて完全な責任を負っていることを知っていることをコンパイラーに伝えています。あなたが間違っていると起こります。
あなたの「何か」のタイプは何ですか?そこにもエラーがあるかもしれません。 &が必要な場合があります。
これは実際には無効です。 2行目の変数ではなく、型に値を代入しています。
void *は汎用ポインタとしてよく使用されます。
C#では、それはのようなもののようになります。
object o = new XmlDocument();
オブジェクトo =新しいリスト();
しかし、C++では、型の安全性はほとんどありません。 IIRCでは、static_castは(キャスト)と同じですが、ランタイム型のチェックは行われません。
本質的に、誰かがMyClassポインタをvoidポインタに格納している可能性があり、コールバックに渡している可能性があります。おそらくコールバックされたこのコードは、それをMyClassとして使用するためにキャストしています。
また、eagerwishesノートの構文エラーがあります。
文脈がなくても、これが何を意味するのか正確に言うのは難しいです。私はあなたが他の誰かのコードに取り組んでいると推測しており、あなたが見せている行はいくつかの機能に散在しているように見えます。
コードの意図については、これがサードパーティのコード/ライブラリを処理するメカニズムであると考えています。独自の型を持つ(テンプレート化されていない)サードパーティライブラリを使用するのはC++で一般的です。それらのライブラリで作成して所有しているデータを一時的に保持する必要がある場合は、ライブラリが自分のタイプを知らなくてもライブラリにアクセスできるようにする必要があります。 1つの例は、コールバック/イベント機能です。イベントが発生したときにライブラリが非同期で通知する場合は、関数ポインタとユーザー定義データを渡す必要があります。そのため、関数が呼び出されると、その関数を処理する方法がわかります。ライブラリは、一般的に、このユーザ提供のデータのvoid *ポインタを取ります。 C++では、ユーザが提供するデータのオブジェクトインスタンスを渡し、コールバックを処理するためにそのオブジェクトに委譲するだけです。コードは次のようになります。
// 3rd-party library API
typedef void (*PingNotifyPtr)(void*);
void NotifyOnPing(PingNotifyPtr, void* userData);
// User Code
void MyNotify(void* myData)
{
MyClass* ptr = (MyClass*)myData;
// do something with ptr
}
void Main()
{
MyClass *pClass = new MyClass();
NotifyOnPing(&MyNotify, pClass);
// the callback is now armed with all the data it needs.
}
多くの図書館では、「void *」引数を宣言することでこれを実現しています。これは、いくつかのメモリ位置への生のポインタです。その場所、整数、クラスインスタンス、文字列などに何かがある可能性があります。サードパーティのライブラリはそのポインタを保持し、ある時点でコードに戻します。
サンプルコードの3行目は、void *ポインタを使用してクラスインスタンスへの参照にキャストしています。 C++の参照は、NULLにすることはできず、値構文を使用する点を除いてポインタと似ています( '。'演算子の代わりに' - > '演算子を使用します)。次に、サンプルコードの4行目で、再構成されたクラスインスタンスのメソッドが使用されます。
とにかく、あなたが扱っているコードベースで4行のコードがすべて連続していると、そのコードは誰かがC++を知らないことを意味します。ここでは1行で同じコードを実行するよりコンパクトな方法です:
((const MyClass*)something)->Foo();
か、あなたは値の構文を好む場合:
(*((const MyClass*)something)).Foo();
幸運を!
一般に、テンプレートは一般的なコレクションに使用されます。あなたが実際にボイドポインタを必要とする非常に少数の場所があります。ボイドポインタは、ハンドルなどの「匿名」型で一般的に使用されます。一般的に、適用可能な場合、テンプレートベースの解決策が好ましい。 –
static_cast <>はCスタイル(キャスト)とまったく同じではありません。 Cスタイルのキャストは、状況に応じてstatic_cast <>、reinterpret_cast <>、const_cast <>、または任意の組み合わせとして機能できます。 –
@ダン:私は、ランタイムチェックは行われていないと言いました。 (Cast)とstatic_cast doestはRTTIに関係しません。 @ジャスパー:私の例はあいまいです。私はC#でオブジェクト参照に任意のクラスを割り当てることができます。 C++では、void *を使ってこれを行い、オブジェクト型を汎用ポインタに割り当てます。 – Alan