C ++リファレンス
参照変数は、別名が既に存在する別の変数の名前である、と言うことです。参照が変数に初期化されたら、参照名または変数を指すように変数の名前を使用することができます。別の実施形態は、参照ポインタによって表されます。
参照とポインタの違い:
ポインタ参照、それらの間の三つの主要な違いがあると混同するのは簡単です:
- リファレンスは空にすることはできません。
- あなたは、指定された参照の後に変更することはできません。
- 作成時に参考に初期化する必要があります。
基本的な使い方
Type& ref = val;
ケース:
#include <iostream>
using namespace std;
int main ()
{
// 声明简单的变量
double d;
// 声明引用变量
// 相当于给变量取一个别名
double& s = d;
// 操作引用就相当于操作本身
s = 11.7;
cout << "Value of d : " << d << endl;
cout << "Value of d reference : " << s << endl;
// 一个变量可以有多个别名
double& y = d;
cout << "Value of other reference : " << y << endl;
// 引用的地址都相同
cout << "d:" << &d << endl;
cout << "s:" << &s << endl;
cout << "y:" << &y << endl;
return 0;
}
結果
Value of d : 11.7
Value of d reference : 11.7
Value of other reference : 11.7
------------
d:0x7ffc8cd21468
s:0x7ffc8cd21468
y:0x7ffc8cd21468
ノートの参照
#include <iostream>
using namespace std;
int main ()
{
//1. 引用必须初始化
//int& ref; //报错:必须初始化引用
//2. 引用一旦初始化,不能改变引用
int a = 10;
int b = 20;
int& ref = a;
ref = b; //不能改变引用
// ref = b; 作用等价于 a = b;
//3. 不能直接对数组建立引用
int arr[10];
//int& ref2[10] = arr;
return 0;
}
配列への参照に
//1. 建立数组引用方法一
// 通过 typedef 定义类型来使用引用
typedef int ArrRef[10];
int arr[10];
ArrRef& aRef = arr;
for (int i = 0; i < 10;i ++){
aRef[i] = i+1;
}
for (int i = 0; i < 10;i++){
cout << arr[i] << " ";
}
cout << endl;
//2. 建立数组引用方法二
int(&f)[10] = arr;
for (int i = 0; i < 10; i++){
f[i] = i+10;
}
for (int i = 0; i < 10; i++){
cout << arr[i] << " ";
}
cout << endl;
結果:
1 2 3 4 5 6 7 8 9 10
10 11 12 13 14 15 16 17 18 19
関数への参照に
**関数のパラメータと戻り値の参照を参照するための最も一般的な場所。**関数のパラメータを基準として使用する場合、パラメータ外部参照への変更が、関数の機能の変化を生成します。もちろん、ポインタを渡すことによって、同じことを行うには、しかし、より明確な構文を参照します。
あなたが関数からリファレンスを返す場合は、同じ関数から返されたポインタとして扱われなければなりません。関数が戻るとき、基準メモリに関連付けられた値が存在しなければなりません。
関数の中で使用される参照パラメータ
//值传递
void ValueSwap(int m,int n){
int temp = m;
m = n;
n = temp;
}
//地址传递
void PointerSwap(int* m,int* n){
int temp = *m;
*m = *n;
*n = temp;
}
//引用传递
void ReferenceSwap(int& m,int& n){
int temp = m;
m = n;
n = temp;
}
void test(){
int a = 10;
int b = 20;
//值传递 没有交换效果
ValueSwap(a, b);
cout << "a:" << a << " b:" << b << endl;
//地址传递
PointerSwap(&a, &b);
cout << "a:" << a << " b:" << b << endl;
//引用传递
ReferenceSwap(a, b);
cout << "a:" << a << " b:" << b << endl;
}
結果
a:10 b:20
a:20 b:10
a:10 b:20
リファレンス構文明確シンプル:
- 関数呼び出しは追加しないときの引数が渡された
&
文字を - 呼び出された関数では、パラメータの前に追加する必要はありません
*
フー
組み込ま別名他の変数は、ポインタを置き換えることができますいくつかのアプリケーションでは、それゆえ、存在します。構文は簡単に参照であるため、C ++置換提唱者は、基準アドレス転送モードによって渡され、より少ないエラーが発生しやすいです。
関数の戻り値に関連して使用
//返回局部变量引用
int& TestFun01(){
int a = 10; //局部变量
return a;
}
//返回静态变量引用
int& TestFunc02(){
static int a = 20;
cout << "static int a : " << a << endl;
return a;
}
int main(){
//不能返回局部变量的引用
// 返回错误: warning: reference to local variable ‘a’ returned
int& ret01 = TestFun01();
//如果函数做左值,那么必须返回引用
TestFunc02();
TestFunc02() = 100;
TestFunc02();
return 0;
}
結果
static int a : 20
static int a : 20
static int a : 100
注意事項
- あなたは返すことはできませんローカル変数の参照を。
- 関数値を去ったとき、参照を返す必要があります。
参照ポインタ
むしろあなたは、このようなポインタかもしれないを変更したい場合には、C言語のコンテンツ、関数宣言を指して指しています:
void fun(int**); // 声明二级指针
エイリアスへのポインタ変数。
Type* pointer = NULL;
Type*& = pointer;
ケース:
struct Person{
int mAge;
};
//指针间接修改teacher的年龄
void AllocateAndInitByPointer(Person** person){
*person = (Person*)malloc(sizeof(Person));
(*person)->mAge = 200;
}
//引用修改teacher年龄
void AllocateAndInitByReference(Person*& person){
person->mAge = 300;
}
void test(){
//创建Teacher
Person* person = NULL;
//指针间接赋值
AllocateAndInitByPointer(&person);
cout << "AllocateAndInitByPointer:" << person->mAge << endl;
//引用赋值,将teacher本身传到ChangeAgeByReference函数中
AllocateAndInitByReference(person);
cout << "AllocateAndInitByReference:" << person->mAge << endl;
free(person);
}
結果
AllocateAndInitByPointer:200
AllocateAndInitByReference:300
関数ポインタパラメータが参照になって、あなたはポインタのアドレスを取得する必要はありません。
定数の参照
フォーマットの定義に一定の基準:
const Type& ref = val;
注意:
-
リテラルの参照が割り当てられることはできませんが、できるconst参照を割り当てます
-
const参照は、修飾された修正することができません。
void test01(){
int a = 100;
const int& aRef = a; // 此时aRef就是a
// aRef = 200; 不能通过aRef的值
a = 100; //OK
cout << "a:" << a << endl;
cout << "aRef:" << aRef << endl;
// 执行结果:
// a:100
// aRef:100
}
void test02(){
// 不能把一个字面量赋给引用
// int& ref = 100;
// 但是可以把一个字面量赋给常引用
const int& ref = 100;
// 等价于: int temp = 100; const int& ret = temp;
}
const参照の使用シナリオ
主に使用される一定の基準関数パラメータ、特にクラスコピー/コピーコンストラクタ。形状パラメータは、定数参照の利点の関数として定義されます。
-
実際のパラメータ受け渡しのオーバーヘッドを削減するための新しい参照変数ません、ありません。
-
参照引数が引き起こす可能性があるのでように定義されるパラメータ変更と変化し、一定の基準は、このような副作用を排除することができます。
あなたは、引数のパラメータが変更されるように変更したい場合は、一般的な参照を使用して、私は、引数としてパラメータを変更したくない、そして、その後、一定の参照を使用しています。
//const int& param防止函数中意外修改数据
void ShowVal(const int& param){}
参照の性質
内部基準の性質はCで実装され++ポインタは一定であります
Type& ref = val; // Type* const ref = &val;
コンパイル時にC ++コンパイラは、多くの場合、同じ基準空間は、ポインタによって占め実装内部参照ポインタとして使用されているが、このプロセスは、ユーザには見えない内部コンパイラの実装、です。
//发现是引用,转换为 int* const ref = &a;
void testFunc(int& ref){
ref = 100; // ref是引用,转换为*ref = 100
}
int main(){
int a = 10;
int& aRef = a; //自动转换为 int* const aRef = &a;这也能说明引用为什么必须初始化
aRef = 20; //内部发现aRef是引用,自动帮我们转换为: *aRef = 20;
cout << "a:" << a << endl;
cout << "aRef:" << aRef << endl;
testFunc(a);
return 0;
}