3

重複の可能性:
C++ の参照変数のサイズ

C++ 参照はメモリを消費しますか? そうでない場合、どうすればそれらを引数として関数に渡すことができますか?

4

1 に答える 1

12

するときもあれば、しないときもあります。必要な場合 (データ メンバーとして使用される場合など) は実行されます。

必要のない例:

int a = 1;
int &b = a;

これで、コンパイラはb純粋に のエイリアスとして扱うことができaます。b参照はオブジェクトではないため、ここにメモリを割り当てる必要はありません。

興味深いかもしれない別のケース:

int some_function_call(); // function returns by value
const int &c = some_function_call();

この場合c、呼び出しの戻り値である一時オブジェクトへの参照です。一時オブジェクトの寿命は のスコープまで延長されるため、その意味では int サイズのメモリcを消費すると言えます。cしかし、コンパイラがそれ以上割り当てる必要がある特別な理由はありません。を記述した場合と同じ出力コードが表示される場合があり、同じ有効期間と同じ名前const int c = some_function_call();のオブジェクトも作成されます。intc

それらをパラメーターとして渡すことについては、パラメーターがメモリを占有するかどうかは、呼び出し規約によって異なります。一部のパラメーターは、レジスターに渡される場合があります。次に、関数の実行中にそのレジスタがスタックのどこかにスピルされるかどうかは、呼び出し先のコードに依存します。ただし、パラメーターとして渡され、関数呼び出しがインライン化されていない場合、参照パラメーターは「何か」を占有する必要があります。これは、呼び出し元が参照によって参照されるオブジェクトのアドレス (「参照先」) を何らかの方法で呼び出し先に知らせる必要があるためです。

ポインターのアドレスを取得しない限り、ポインターについても同じことが言えます。しかし、ポインターの場合は、コンパイラー自身のイニシアチブによる最適化です。参照の場合、それらは標準でエイリアスとして明示的に定義されており、コンパイラが参照を純粋にエントリとして扱うことができない場合、ポインター (または少なくともアドレス) はたまたまそれを実装するための明白な手段です。コンパイル時の名前ルックアップ テーブル。唯一の本質的な違いは、標準で記述された抽象マシンで何が起こるかです。実装と最適化の後は、同じことになる可能性があります。

于 2012-12-20T11:28:52.813 に答える