web-dev-qa-db-ja.com

C ++のハンドルとは何ですか?

ハンドルは一種のポインターであるが、そうではなく、オブジェクト自体ではなくオブジェクトへの参照を保持できると言われました。より詳細な説明は何ですか?

91
Xenoprimate

ハンドルは、整数インデックスからカーネル空間内のリソースへのポインタまで何でもかまいません。アイデアは、リソースの抽象化を提供するため、リソースを使用するためにリソース自体について多くを知る必要はありません。

たとえば、Win32 APIのHWNDはWindowのハンドルです。それ自体は役に立たない:あなたはそこから情報を収集することはできません。ただし、適切なAPI関数に渡すと、さまざまなトリックを実行できます。内部的には、HWNDはGUIのウィンドウテーブルへの単なるインデックスと考えることができます(これは必ずしも実装方法とは限りませんが、魔法の意味を成します)。

編集:あなたが質問で具体的に何を求めていたのか、100%確実ではありません。これは主に純粋なC/C++について話しています。

93
Matthew Iselin

ハンドルは、目に見える型がアタッチされていないポインターまたはインデックスです。通常、次のようなものが表示されます。

 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);
     }
 }
47
jmucchiello

ハンドルisは、通常、何らかのエンティティを参照する方法であるという点で、一種のポインターです。

ポインターはハンドルの一種であると言う方が正確ですが、すべてのハンドルがポインターであるとは限りません。

たとえば、ハンドルは、メモリテーブルへのインデックスである場合があります。これは、オブジェクト自体へのポインタを含むエントリに対応します。

重要なことは、「ハンドル」を持っているとき、そのハンドルが実際に識別するものを識別する方法を知らず、気にもしないことです。

また、「ハンドルとは何か」に対する単一の答えはないことも明らかです。なぜなら、同じシステムであっても、さまざまなものへのハンドルは「内部」で異なる方法で実装される可能性があるからです。ただし、これらの違いを気にする必要はありません。

27
Deltics

C++/CLIでは、ハンドルはGCヒープにあるオブジェクトへのポインターです。 (アンマネージド)C++ヒープでのオブジェクトの作成は、newを使用して実現され、new式の結果は「通常の」ポインターです。管理対象オブジェクトは、gcnew式を使用してGC(管理対象)ヒープに割り当てられます。結果はハンドルになります。ハンドルに対してポインター演算を行うことはできません。ハンドルを解放しません。 GCがそれらを処理します。また、GCは、マネージヒープ上のオブジェクトを自由に再配置し、プログラムの実行中に新しい場所を指すようにハンドルを更新します。

5
Mehrdad Afshari

これは Handle-Body-Idiom のコンテキストで表示されます。これはPimplイディオムとも呼ばれます。実際のデータを別のクラスオブジェクトに保持することで、ライブラリのABI(バイナリインターフェイス)を同じに保つことができます。これは、そのクラスに委任する関数で構成される「ハンドル」オブジェクトに保持されるポインタによってのみ参照されます体"。

また、2つのオブジェクトの一定時間および例外セーフスワップを有効にすると便利です。このためには、bodyオブジェクトを指すポインターを交換するだけです。

ハンドルは、あなたが望むものです。

ハンドルは、ルックアップテーブルで使用される符号なし整数にすることができます。

ハンドルは、より大きなデータセットへのポインタ、またはデータセットへのポインタにすることができます。

ハンドルを使用するコードの動作に依存します。それがハンドルタイプを決定します。

handle」という用語が使用される理由は重要です。これは、オブジェクトの識別またはアクセスタイプとしてそれらを示します。つまり、プログラマにとって、それらは「キー」を表しますまたは何かへのアクセス。

1
dyasta

HANDLE hnd;void * ptr;と同じです

HANDLEは、Visual Studio(Windows)のwinnt.hファイルで定義されているtypedefです。

typedef void *HANDLE;

HANDLE の詳細を読む

1
Kulamani