C++ リファレンス (&) のメモ
1. レジスタは通常 4/8 バイトしかないため、リターン時に中間変数 (下図の一時変数) がレジスタに格納されるとは限りません。
2. 参照による返却によりコピーが減り、効率が向上します。
ただし、スタック フレームが破棄されると、ランダムな値を取得するためにスタック フレームがクリーンアップされるため、印刷の実行は間違っています。
正しい表現:
3. 一時変数は定数です
このようなコードはコンパイルできません。ここに 1 つが関与しているためです权限的放大
。 については引用
、権限を拡大することはできず、権限の縮小/翻訳のみが可能であるためです。
ここの一時変数はa
定数なので、実際には変換const double
からここまでの権限を削減した型なのでエラーが報告されますが、変更すればコンパイル可能です。const double
int
const int &c=a;
なぜ一時変数があるのでしょうか?
i
とherej
を比較する場合、タイプが異なるため、通常は小さいタイプから大きいタイプにタイプをアップグレードする必要があります。たとえば、ここでの比較は元の変数int
にアップグレードする必要がありdouble
、ここでのプロモーションはi
元の変数をアップグレードすることです。比較のせいで元の変数の型が変わってしまうとめちゃくちゃになってしまいませんか?したがって、ここで一時変数が生成され、一時変数の型が昇格されてから とj
比較されます。
4. 参照用のスペースはありますか?
文法レベルから見ると、オープンスペースはなく、変数の別名です。アセンブリの観点からはどうなのでしょうか?
pa
まず、ポインタのアセンブリ コードを見てください。まず、 a
a のアドレスを register に格納しeax
、次にeax
(格納されている a のアドレス) を に与えpa
、次に のpa
アドレスを register に与えますeax
。[eax]
つまり、eax
参照を解除して、与えます。1Eh(30)
にeax
。
次に、リファレンスのアセンブリ コードを見ると、ポインタの動作とほぼ同じであることがわかります。そのため、最下層から見ると、リファレンスによって追加のスペースが確保され、リファレンスは以下と同様の方法で実装されています。ポインタ
参照とポインタの違い:
- 参照は概念的に変数の別名を定義し、ポインターは変数のアドレスを格納します。
- 参照は定義時に初期化する必要があり、ポインタは必要ありません
- 初期化中に参照がエンティティを参照した後は、他のエンティティを参照すること、ポインタはいつでも同じタイプのエンティティを指すことができます。
- NULL参照はありませんが、NULL ポインターはあります
sizeof
意味は異なります。参照結果は参照型のサイズですが、ポインタは常にアドレス空間が占有するバイト数(32)になります。プラットフォームの下の 4 バイト)
- 参照の自己インクリメントは、参照されるエンティティが 1 ずつ増加することを意味し、ポインターの自己インクリメントは、ポインターが型のサイズを後方にオフセットすることを意味します。
- マルチレベル ポインタはありますが、マルチレベル参照はありません
- エンティティは別の方法でアクセスされ、ポインタは明示的に逆参照される必要があり、参照はコンパイラ自体によって処理されます。
- 参照はポインタより安全です