web-dev-qa-db-ja.com

違いは何ですか:ハンドル、ポインター、参照

ハンドルはオブジェクトへのポインターとどのように異なりますか。また、参照への参照ができないのはなぜですか。

22
quantum231

ハンドルは通常、オブジェクトへの不透明参照です。ハンドルのタイプは、参照される要素とは無関係です。たとえば、open()システムコールによって返されるファイル記述子について考えてみます。タイプはintですが、開いているファイルテーブルのエントリを表します。テーブルに格納されている実際のデータは、open()によって返されたintとは無関係です。つまり、実装は互換性を維持する必要がなくなります(つまり、実際のテーブルは、ユーザーコードに影響を与えることなく透過的にリファクタリングできます。ハンドルは、同じライブラリインターフェイスの関数でのみ使用できます。これにより、ハンドルを実際のオブジェクトに再マップできます。

ポインタは、メモリ内のアドレスと、そのメモリ位置にあるオブジェクトのタイプの組み合わせです。値はアドレスであり、ポインターのタイプはコンパイラーに、そのポインターを介して実行できる操作、メモリー位置の解釈方法を指示します。ポインタはtransparentであり、参照されるオブジェクトには、ポインタから存在する具象型があります。場合によっては、ポインタがハンドル(void*は完全に不透明で、空のインターフェースへのポインタも不透明です)。

参照はオブジェクトへのaliasesです。そのため、参照への参照は使用できません。オブジェクトには複数のエイリアスを使用できますが、エイリアスのエイリアスは使用できません。ポインタと同様に、参照が型付けされます。状況によっては、参照は使用時に自動的に逆参照されるポインターとしてコンパイラーによって実装できます。他の場合では、コンパイラーは実際のストレージを持たない参照を持つことができます。重要な部分は、それらがオブジェクトに対してaliasesであることです。これらはオブジェクトで初期化する必要があり、初期化後に別のオブジェクトを参照するために再装着することはできません。それらが初期化されると、参照のすべての使用は実際のオブジェクトの使用になります。

「なぜリファレンスへの参照ができないのですか?」参照isが理解できないことを意味します。

参照はオブジェクトの別名です。これ以上何もない。変数Xにオブジェクトを格納している場合、このオブジェクトへの参照である変数Yを作成できます。どちらも同じオブジェクトについて話しているので、Yへの参照があるとはどういう意味ですか?それらはすべて同じものを参照しているので、Xへの参照を持つことと何ら変わりはありません。

「ハンドル」には、C++言語に関する限り、定義はありません。一般的に言えば、「ハンドル」は、ある種のリソースを表す何らかの形の構造です。リソースを作成するいくつかのAPIから取得します。リソースの状態を照会または変更するには、ハンドルをパラメーターとして取る関数を呼び出します。そして、それを使い終わったら、他のAPI関数に渡します。

ポインタcouldはハンドルです。参照はハンドルである可能性があります。オブジェクトはハンドルである場合があります。 integerはハンドルである可能性があります。それはすべて、ハンドルを実装するシステムがそれをどのように処理したいかによって異なります。

14
Nicol Bolas

handleは「マジッククッキー」とも呼ばれます。オブジェクトを識別する不透明なタイプの単なる値です。場合によっては、実際のポインターとして実装されるため、正しい型へのポインターにキャストすると、逆参照して、それが指すあらゆる種類のオブジェクトを操作できます。

他の場合では、それはポインター以外のものとして実装されます-たとえば、そのタイプのオブジェクトのテーブルがあり、ハンドルは実際にはそのテーブルへの単なるインデックスです。テーブルのベースアドレスがわからない場合は、インデックスを使用してほとんど何もできません。

C++は、参照への参照は不可能であると単に述べています。 「理由」はそれほどありません。もしもひどくやりたかったのなら、間違いなくそれを許していたはずです(それについては、参照の配列も同様です)。しかし、参照を(多く)制限するのが最善であるという決定が下されたので、それが彼らがしたことです。

10
Jerry Coffin

違いはコンテキストです。

ハンドルの基本的な意味は、それが非常に限られたコンテキストでいくつかのオブジェクトを参照することです。例えば。 OSは、ユーザーまたはpidのために開いた20ファイルのみを保持できます。ポインタは、「メモリ」のコンテキストで同じオブジェクトを参照します。参照はオブジェクトへの「エイリアス」です。ソースコードのコンテキストでオブジェクトを参照します。したがって、参照はすでにオブジェクトであるので、参照への参照は存在しません。

5
Aki Suihkonen