C++ を使い始めた頃 (かなり前)、私は Java の学者に囲まれていました。Java に対する C++ の利点を尋ねられた場合 (通常、私は不自然であると却下しようとする質問ですが、そのとおりです)、C++ が参照とポインターを提供したことを回答に含めます。Java の担当者は信じられないような顔をして、参照はポインターであると提案し、私を笑い飛ばして部屋から追い出しました。私は、C++ では参照とポインターが異なると主張しました。
そして、公平を期すために、私は正しかった。参照とポインターは、意味的にも構文的にも異なります。残念ながら、私は自分の主張を誤った考えで裏付けました。つまり、根底にある実装が異なっていたということです。
aがストレージのない型エイリアスであるのと同じように、標準化により、参照は構文内の名前エイリアスであるというのが私の確固たる信念でした。typedef
参照はオブジェクトではなく、ストレージがなく、「名前」から「オブジェクト」への複数の最上位マッピングを提供しているだけだと確信していました。その点で、ファイルシステムのソフトリンクのようなものだと思いました:
Code: int a = 3; int& b = a;
Names Objects Memory
+-----+ +-------------+ +-------+
| a |---->| | | |
+-----+ | | | |
| int |---->| 3 |
+-----+ | | | |
| b |---->| | | |
+-----+ +-------------+ +-------+
もちろん、最適化がこれにつながる可能性がありますが、参照にはストレージがあります。構文がプログラマーからそれを抽象化するために最善を尽くしたとしても、それらは別個のオブジェクトです。
言うまでもなく、最適化がオフになっているコンパイラーが参照をポインターとして実装する可能性があり、逆参照操作が必要になる可能性があることを知ってがっかりしました。実際には、ファイルシステムのハードリンクに類似したものを作成していたのです。
Code: int a = 3; int& b = a;
Names Objects Memory
+-----+ +-------------+ +-------+
| a |---->| int |---->| |
+-----+ +-------------+ | |
| 3 |
+-----+ +-------------+ | |
| b |---->| int& |---->| |
+-----+ +-------------+ +-------+
標準 C++ では、参照を実装する方法を実際に指定していないため、私の理論は一部のツールチェーンに当てはまる可能性がありますが、主流のコンパイラにはありません...そしてそれは確かに標準には記載されていません。