ハンドルは一種のポインタであるが、そうではなく、オブジェクト自体ではなくオブジェクトへの参照を維持できると言われました。より複雑な説明とは何ですか?
ハンドルは一種のポインタであるが、そうではなく、オブジェクト自体ではなくオブジェクトへの参照を維持できると言われました。より複雑な説明とは何ですか?
回答:
ハンドルは、整数インデックスからカーネルスペース内のリソースへのポインターまで何でもかまいません。アイデアは、それらがリソースの抽象化を提供するので、それを使用するためにリソース自体について多くを知る必要はないということです。
たとえば、Win32 APIのHWNDはウィンドウのハンドルです。それ自体では役に立たないので、そこから情報を収集することはできません。しかし、それを適切なAPI関数に渡すと、それを使用してさまざまなトリックを実行できます。内部的には、HWNDをGUIのウィンドウのテーブルへの単なるインデックスと考えることができます(これは必ずしも実装方法とは限りませんが、それは魔法の理にかなっています)。
編集:あなたが質問で具体的に何を求めていたのか100%確実ではありません。これは主に純粋なC / C ++について話しています。
ハンドルは、可視の型が関連付けられていないポインターまたはインデックスです。通常、次のようなものが表示されます。
typedef void* HANDLE;
HANDLE myHandleToSomething = CreateSomething();
したがって、コードでは、HANDLEを不透明な値として渡すだけです。
オブジェクトを使用するコードでは、ポインターを実際の構造体型にキャストして使用します。
int doSomething(HANDLE s, int a, int b) {
Something* something = reinterpret_cast<Something*>(s);
return something->doit(a, b);
}
または、配列/ベクトルのインデックスとして使用します。
int doSomething(HANDLE s, int a, int b) {
int index = (int)s;
try {
Something& something = vecSomething[index];
return something.doit(a, b);
} catch (boundscheck& e) {
throw SomethingException(INVALID_HANDLE);
}
}
ハンドルは、ある種のエンティティを参照する方法であるという点で一種のポインタです。
ポインタはハンドルの1つのタイプであると言う方がより正確ですが、すべてのハンドルがポインタであるとは限りません。
たとえば、ハンドルは、メモリ内テーブルへのインデックスでもあります。これは、それ自体が何らかのオブジェクトへのポインタを含むエントリに対応しています。
重要なことは、「ハンドル」を持っている場合、そのハンドルが実際にそれが識別するものをどのようにして識別してしまうのかを知らず、気にもしないということです。
同じシステムであっても、異なるものへのハンドルは「内部」で異なる方法で実装される可能性があるため、「ハンドルとは何か」に対する単一の回答がないことも明らかです。しかし、それらの違いを気にする必要はありません。
C ++ / CLIでは、ハンドルはGCヒープにあるオブジェクトへのポインターです。(アンマネージ)C ++ヒープ上にオブジェクトを作成するには、を使用new
しnew
ます。式の結果は「通常の」ポインターです。管理対象オブジェクトは、gcnew
式を使用してGC(管理対象)ヒープに割り当てられます。結果はハンドルになります。ハンドルに対してポインター演算を行うことはできません。ハンドルを解放しません。GCがそれらを処理します。また、GCは、プログラムの実行中に、マネージヒープ上のオブジェクトを自由に再配置し、新しい場所を指すようにハンドルを更新できます。
これは、Pimpl イディオムとも呼ばれるHandle-Body-Idiomのコンテキストで表示されます。これにより、実際のデータを別のクラスオブジェクトに保持することにより、ライブラリのABI(バイナリインターフェイス)を同じに保つことができます。これは、「ハンドル」オブジェクトに保持されたポインタによって参照されるだけであり、そのクラスにデリゲートする関数で構成されます体"。
また、2つのオブジェクトの一定時間および例外セーフスワップを有効にすることも役立ちます。このためには、ボディオブジェクトを指すポインタを交換するだけです。