C++ 参照とポインタの比較

参照は C++ における概念で、初心者は参照とポインタを混同しやすいです。

以下のプログラムでは、n は m の参照(reference)であり、m は被参照オブジェクト(referent)です。

int m; 
int &n = m; 

n は m の別名(あだ名)に相当し、n に対するあらゆる操作は m に対する操作です。

したがって、n は m のコピーでもなく、m を指すポインタでもなく、実際には n は m 自身です。

参照の規則:

  • (1)参照は作成と同時に初期化されなければなりません(ポインタはいつでも初期化できます)。
  • (2)NULL 参照は存在できません。参照は正当な記憶域と関連付けられなければなりません(ポインタは NULL でもかまいません)。
  • (3)参照は一度初期化されると、参照の関係を変更できません(ポインタはいつでも指すオブジェクトを変更できます)。

以下のサンプルプログラムでは、k は i の参照として初期化されています。

文 k = j は k を j の参照に変更するのではなく、単に k の値を 6 に変更するだけです。

k は i の参照であるため、i の値も 6 になります。

int i = 5; 
int j = 6; 
int &k = i; 
k = j; // k 和 i 的值都变成了 6;

参照の主な機能は、関数の引数と戻り値を渡すことです。

C++ 言語では、関数の引数と戻り値の受け渡し方法は3つあります:値渡し、ポインタ渡し、参照渡しです。

以下は「値渡し」のサンプルプログラムです。

Func1 関数体内の x は外部変数 n のコピーであるため、x の値を変更しても n には影響しません。したがって、n の値は依然として 0 です。

void Func1(int x) 
{ 
    x = x + 10; 
} 
... 
int n = 0; 
Func1(n); 
cout << "n = " << n << endl; // n = 0 

以下は「ポインタ渡し」のサンプルプログラムです。

Func2 関数体内の x は外部変数 n を指すポインタであるため、そのポインタの内容を変更すると n の値が変わります。したがって、n の値は 10 になります。

void Func2(int *x) 
{ 
    (* x) = (* x) + 10; 
} 
... 
int n = 0; 
Func2(&n); 
cout << "n = " << n << endl; // n = 10 

以下は「参照渡し」のサンプルプログラムです。

Func3 関数体内の x は外部変数 n の参照であり、x と n は同じものです。x を変更することは n を変更することに等しいため、n の値は 10 になります。

void Func3(int &x) 
{ 
    x = x + 10; 
} 
... 
int n = 0; 
Func3(n); 
cout << "n = " << n << endl; // n = 10

上記の3つのサンプルプログラムを比較すると、「参照渡し」の性質は「ポインタ渡し」に似ており、記述方法は「値渡し」に似ていることがわかります。

実際には「参照」でできることはすべて「ポインタ」でもできます。なぜ「参照」というものが必要なのでしょうか?

答えは「適切な道具でふさわしい仕事をする」ことです。

ポインタはメモリ内のあらゆるものを制約なく操作できます。ポインタは強力ですが、非常に危険です。

本当にあるオブジェクトの「別名」を借りるだけでよい場合は、「ポインタ」ではなく「参照」を使用してください。事故を防ぐためです。