2009-08-19 4 views
76

私は、ハンドルはポインタのようなものだと言われていますが、オブジェクト自体ではなくオブジェクトへの参照を保持することができます。もっと丁寧な説明は何ですか?C++のハンドルとは何ですか?

+6

http://en.wikipedia.org/wiki/Handle_%28computing%29 – Jherico

+0

「責任の連鎖」パターンを見ると、「ハンドル」は基本的にノードであり、「ハンドラ」は、それらの小さなセットです。 "魔法"は再帰に由来します。 –

答えて

79

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

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

編集:100%あなたの質問で具体的に何を求めていたのでしょうか。これは、主に純粋なC/C++について語っています。

+10

ハンドルは、(特に)状態を保存するのに便利です。あなたはstd :: vectorのような構造のデータを持っている場合。あなたのオブジェクトは、プログラムの実行中に異なる時間に異なるメモリ位置にあるかもしれません。つまり、そのメモリへのポインタは値を変更します。ハンドルは変更されず、常にオブジェクトを参照します。 (ゲームのような)プログラムの状態を保存すると想像してください。ポインタの場所をデータに保存せず、後でデータを再度インポートし、メモリ内のそのアドレスを取得しようとします。ただし、データでハンドルを保存し、データとハンドルをインポートすることができます。 – SinisterRainbow

+0

LinuxでHANDLEを同等のものに変換することはできますか? WindowsからLinuxにHANDLEを使用するプログラムを移行する必要があります。 –

+1

これは正解です。何でも構いませんし、ハンドルを使用するコードによってハンドルのタイプが定義されています。私は自分の似たような答えのより簡潔なバージョンを作ろうとしました、後世のために自分自身を助けることができませんでした。 @CornelVerster - 彼らはLinuxで同じです。つまり、OSのハンドルではなく、その概念です。したがって、それはそのマイグレーションに関してハンドルに依存し、あるいはマイグレーションする必要があります。 –

4

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

4

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

2つのオブジェクトの一定時間と例外セーフなスワップを有効にすると便利です。このためには、本体オブジェクトを指すポインターをスワップしなければなりません。

25

ハンドルです。これは通常、ある種のエンティティを参照する方法です。

ポインタはハンドルの1つのタイプですが、すべてのハンドルがポインタではないと言う方がより正確です。

たとえば、ハンドルは、メモリテーブルへの何らかのインデックスであってもよく、これはそれ自体が何らかのオブジェクトへのポインタを含むエントリに対応する。

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

同じシステム内であっても、異なるものへのハンドルは「フードの下で」さまざまな方法で実装できるため、「正確にはハンドルです」という単一の答えはないことも明らかです。しかし、あなたはそれらの違いに心配する必要はありません。

+1

この回答は補足ですhttps://stackoverflow.com/a/1923646/2188550 – Ivanzinho

41

ハンドルは、可視タイプが接続されていないポインタまたはインデックスです。通常は次のように表示されます。

typedef void* HANDLE; 
HANDLE myHandleToSomething = CreateSomething(); 

したがって、コードでは、不透明な値としてハンドルを渡すだけです。オブジェクトを使用するコードで

、それは実際の構造型へのポインタをキャストし、それを使用する:

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); 
    } 
} 
0
HANDLE hnd; is same as void * ptr; 

HANDLEはビジュアルスタジオ(ウィンドウ)のwinnt.hファイルで定義されたtypefedです。

i.c:typedef void *HANDLE;

よりおよそHANDLE

+1

これはWindowsのみに適用され、Windowsアーキテクチャで使用される多くの種類のハンドルのうちの1つのみです。ただし、**は**通常のWindowsアプリケーションレベルハンドルと呼ばれるものです。 –

0

ハンドル読むには、あなたがそれになりたいものは何でもあります。

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

ハンドルは、より大きいデータセットへのポインタまたはその中へのポインタです。

ハンドルを使用するコードの動作によって異なります。それはハンドルのタイプを決定します。

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