(1)什麼是引用?
引用就是變數的別名,操作一個變數的引用也就相當於操作變數本身,這一點跟指標很類似,但是操作引用不用像操作指標一樣,利用取地址符號,很不方便。而操作引用的話,則跟操作普通變數一樣,所以C++之中更加鼓勵使用引用。
(2)C++函數為什麼要使用引用?
C語言之中大量利用指標作為形參或者函數傳回值,這是由於值拷貝會有很大的消耗(比如傳入傳出一個大的結構體)。所以在C++之中使用引用作為函數參數和傳回值的目的和使用指標是一樣的。而且形式上更加直觀,所以C++提倡使用引用。
(3)C++返回引用?
前面提到利用引用作為函數形參和傳回值的好處。
C++之中函數的返回分為以下幾種情況:
1)main的傳回值:返回0表示運行成功。
2)返回非參考型別:函數的傳回值用於初始化在跳出函數時候建立的臨時對象。用函數傳回值來初始化臨時對象與用實參初始化形參的方法是一樣的。如果傳回型別不是引用的話,在函數返回的地方,會將傳回值複製給臨時對象。且其傳回值既可以是局部對象,也可以是運算式的結果。
3)返回引用:當函數返回參考型別的時候,沒有複製傳回值,而是返回對象的引用(即對象本身)。
函數返回引用:實際上是一個變數的記憶體位址,既然是記憶體位址的話,那麼肯定可以讀寫該地址所對應的記憶體地區的值,即就是“左值”,可以出現在指派陳述式的左邊。
1)函數返回引用的時候,可以利用全域變數(作為函數返回),或者在函數的形參表中有引用或者指標(作為函數返回),這兩者有一個共同點,就是返回執行完畢以後,變數依然存在,那麼返回的引用才有意義。
exp1:
View Code
1 #include <iotream>
2
3 int global_variable; //global variable
4
5 int &f(int t1, int t2) //return the reference of the global variable "global_variable"
6
7 {
8
9 global_variable = t1 + t2;
10
11 return global_variable;
12
13 }
14
15 int main(void)
16
17 {
18
19 int f = f(1, 3);
20
21 std::cout << global_variable << std::endl; //L1
22
23 f(2, 8)++;
24
25 std::cout << global_variable << std::endl; //l2
26
27 f(2, 3) = 9;
28
29 std::cout << global_variable << std::endl; //L3
30
31 return 0;
32
33 }
L1:執行過f(1,3),則global_variable變為4。
L2:執行過f(2,8)++,f(2,8)為10,可以執行++(表示其為左值),變為11。
L3:執行f(2,3),global_variable變為5,由於其是左值,修改了global_variable的值,為9。
exp2:
View Code
#include <iostream>
int &t(int a, int b, int &result)
{
result = a + b;
return result;
}
int &f(int a, int b, int *result)
{
*result = a + b;
return *result;
}
int main(void)
{
int t_variable;
int *f_variable = new int;
t(1, 2, t_variable)++;
std::cout << t_variable << std::endl; //t_variable = 4
f(1, 2, f_variable)--;
std::cout << *f_variable << std::endl; //t_variable = 2
delete f_variable;
return 0;
}
exp3:
int &t(int a, int b)
{
return a+b; //now allowed
}
2)由於返回的是生命期在函數退出的時候還存在的變數地址,所以函數傳回值做的任何操作就相當於對這個變數地址指向的變數做的操作。如果在傳回值前面加const那麼這個變數就不允許被修改。
View Code
#include <iostream>
const int &t(int a, int b, int &result)
{
result = a + b;
return result;
}
int main()
{
int t_variable;
t(1, 2, t_variable);
std::cout << t_variable << std::endl; //t_variable = 3
t(1, 2, t_variable)++;
std::cout << t_variable << std::endl; //not allowed
}
小結:
(1)使用引用當作函數參數和傳回值,效率更高。
(2)函數返回的對象引用,必須在調用函數前就已經存在,不允許返回局部變數的引用!
(3)當不希望返回的對象被修改的時候,可以添加const。