C++ 参照
参照変数はエイリアスです。つまり、既に存在する変数の別名です。
参照をある変数に初期化すると、その参照名または変数名を使用して変数を指すことができます。
参照は定義時に初期化する必要があり、いったん変数にバインドされると、他の変数にバインドし直すことはできません。
参照の構文は次のとおりです:
int a = 10; int &ref = a; // ref 是 a 的引用
int &ref示しますrefは...ですint型の参照。refであるaの別名であり、...に対するref操作は直接...に作用しますa。
C++ 参照 vs ポインタ
参照はポインタと混同されやすいですが、両者には3つの大きな違いがあります:
- 空の参照は存在しません。参照は有効なメモリに接続されている必要があります。
- 参照がいったんオブジェクトに初期化されると、別のオブジェクトを指すことはできません。ポインタはいつでも別のオブジェクトを指すことができます。
- 参照は作成時に初期化する必要があります。ポインタはいつでも初期化できます。
- 参照の対象は変数でなければならず、ポインタはアドレスでなければなりません。
| 特性 | 参照 | ポインタ |
|---|---|---|
| 定義と初期化 | 初期化が必須であり、...になることはできませんnull。 | 初期化しなくてもよく、後続のコードで他のオブジェクトを指すことができ、...にすることができますnull。 |
| 構文 | 使用&宣言します。例:int &ref = a; | 使用*宣言します。例:int *ptr = &a; |
| 再バインド | 再バインドはできません。初期化後は常に同じオブジェクトを参照します。 | 他のオブジェクトを指し直すことができます。例:ptr = &b; |
| ヌル値(Nullability) | ...になることはできませんnull有効なオブジェクトにバインドする必要があります。 | ...にすることができますnullどのオブジェクトも指していないことを示します。 |
| メモリ使用量 | 追加のメモリを消費しません(コンパイラは通常、参照されるオブジェクトを直接操作するように最適化します)。 | 追加のメモリを消費します(アドレスを格納します。通常はマシンワード長、例えば4バイトまたは8バイトです)。 |
| アクセス方法 | 逆参照演算子を使わずに直接使用します。例:ref = 10; | 使用する必要があります*逆参照演算子を使用して、指しているオブジェクトにアクセスまたは変更します。例:*ptr = 10; |
| 多段間接参照 | 多段間接参照には対応していません(参照の参照はできません)。 | 多段間接参照に対応しています(例:ポインタのポインタ:int **pptr;)。 |
| 関数の引数渡し | 関数の引数渡しによく使用され、構文が簡潔です。例:void func(int &x) { x = 10; } | 関数の引数渡しにも使用できますが、逆参照演算子を使用する必要があります。例:void func(int *x) { *x = 10; } |
| 配列と参照 | 参照の配列を直接作成することはできませんが、配列への参照は作成できます。例:int (&ref)[10] = arr; | ポインタの配列を作成できます。また、配列へのポインタも作成できます。例:int *ptrArr[10]; |
| 安全性 | より安全で、...になることはできませんnull、しかも構文がより直感的です。 | より柔軟ですが、エラーが発生しやすいです(ヌルポインタ、未初期化ポインタなど)。 |
| 内部実装 | 通常はポインタを介して実装されますが、コンパイラは参照されるオブジェクトを直接操作するように最適化します。 | ターゲットオブジェクトのメモリアドレスを直接格納します。 |
C++ での参照の作成
変数名は変数がメモリ内の位置に付けたラベルだと考えてください。参照は、変数がメモリ内の位置に付ける2番目のラベルと見なすことができます。したがって、元の変数名または参照を使って変数の内容にアクセスできます。例:
int i = 17;
以下のように、i の参照変数を宣言できます。
int& r = i; double& s = d;
これらの宣言では、&は...と読みます参照。
したがって、最初の宣言は次のように読めます。「r は i に初期化された整数型の参照です」、2番目の宣言は次のように読めます。「s は d に初期化された double 型の参照です」。
以下の例では int と double の参照を使用しています。
例
#include <iostream>
using namespace std;
int main ()
{
// 単純な変数を宣言
int i;
double d;
// 参照変数を宣言
int& r = i;
double& s = d;
i = 5;
cout << "Value of i : " << i << endl;
cout << "Value of i reference : " << r << endl;
d = 11.7;
cout << "Value of d : " << d << endl;
cout << "Value of d reference : " << s << endl;
return 0;
}
上記のコードをコンパイルして実行すると、次の結果が生成されます。
Value of i : 5 Value of i reference : 5 Value of d : 11.7 Value of d reference : 11.7
参照は通常、関数のパラメータリストと関数の戻り値に使用されます。以下に、C++ プログラマーが必ず理解しておくべき、C++ 参照に関連する2つの重要な概念を示します。
| 概念 | 説明 |
|---|---|
| 参照を引数として使用 | C++ は、参照を引数として関数に渡すことをサポートしています。これは通常の引数を渡すよりも安全です。 |
| 参照を戻り値として使用 | C++ 関数から、他のデータ型を返すのと同様に参照を返すことができます。 |