什么是引用?

引用就是對變量起一個別名,而變量還是原來的變量,并沒有重新定義一個變量。例如下面的例子:

 

平面設(shè)計培訓(xùn),網(wǎng)頁設(shè)計培訓(xùn),美工培訓(xùn),游戲開發(fā),動畫培訓(xùn)

 1 #include<iostream> 2 using namespace std; 3   4   5 int main() 6 { 7       int a = 10; 8       int& n = a; 9       cout<<a<<endl;10       cout<<n<<endl;11       cout<<&a<<endl;12       cout<<&n<<endl;13  14       return 0;15 }

平面設(shè)計培訓(xùn),網(wǎng)頁設(shè)計培訓(xùn),美工培訓(xùn),游戲開發(fā),動畫培訓(xùn)

 

 程序的運行結(jié)果為:

 

平面設(shè)計培訓(xùn),網(wǎng)頁設(shè)計培訓(xùn),美工培訓(xùn),游戲開發(fā),動畫培訓(xùn)

 

我們可以看到變量a和變量a的引用(別名)n所指向的就是同一片空間,而且別名n并沒有創(chuàng)建一個新的變量

 

在引用的時候我們應(yīng)該注意一些問題:

1.一個變量可以有多個別名

2.引用必須初始化

3.引用只可以在變量初始化的時候引用一次,之后不可以在引用其他的變量(這個想要引用其他的變量幾乎是無法實現(xiàn),反正我沒辦法)

 常引用

現(xiàn)在我們了解了什么是引用,而常引用是非常容易出現(xiàn)錯誤的一種引用,下面我們展開討論

以下代碼就是相關(guān)的用法:

平面設(shè)計培訓(xùn),網(wǎng)頁設(shè)計培訓(xùn),美工培訓(xùn),游戲開發(fā),動畫培訓(xùn)

 1 int main() 2 { 3       int d1 = 4; 4       const int & d2 = d1; 5       d1 = 5;             // d1改變d2的值也會改變。 6 //    d2 = 6;             // 不能給常量(不能被修改的量)賦值 7       const int d3 = 1; 8       const int & d4 = d3; 9 //    int&d5 = d3;10       const int & d6 = 5; // 常量具有常性,只有常引?可以引?常量11       double d7 = 1.1;12 //    int& d8 = d7; //d7是double類型,d8是int,d7賦值給d8時要生成一個臨時變量13       //也就是說d8引?的是這個帶有常性的臨時變量,所以不能賦值。14       const int& d9 = d7;15       return 0;16 }

平面設(shè)計培訓(xùn),網(wǎng)頁設(shè)計培訓(xùn),美工培訓(xùn),游戲開發(fā),動畫培訓(xùn)

 

從以上的代碼中我們就可以知道const引用時應(yīng)該注意的問題。

 

引用可以作為函數(shù)的參數(shù)也可以作為函數(shù)的返回值來使用,但是我們在使用的時候應(yīng)該注意些什么呢?

1.引用作為函數(shù)的參數(shù)時

       在函數(shù)傳參的時候,在C語言中有兩種方式,一種是值傳遞,還有一種是址傳遞,也就是指針傳遞,而在C++中我們則引入了引用傳遞。這三種傳遞的方式各有各的特點的,這里我們著重說一下引用傳遞的特點

平面設(shè)計培訓(xùn),網(wǎng)頁設(shè)計培訓(xùn),美工培訓(xùn),游戲開發(fā),動畫培訓(xùn)

 1 #include<iostream> 2 using namespace std; 3 #include <Windows.h> 4 struct BigData 5 { 6       int array [1000]; 7 }; 8 void DealBigData1(BigData& x) 9 {10       x.array[0] = 0;11       x.array[1] = 1;12       x.array[2] = 2;13 }14 void DealBigData2 (BigData x)15 {16       x.array [0]= 0;17       x.array [1]= 1;18       x.array [2]= 2;19 }20 void TestReference()21 {22       BigData bd ;23       int begin = GetTickCount ();24       for (int i = 0; i < 1000000; ++i )25       {26             DealBigData1(bd);27       }28       int end = GetTickCount ();29       cout<<"cost time:" <<end - begin<<endl ;30       begin = GetTickCount ();31       for (int i = 0; i < 1000000; ++i )32       {33             DealBigData2(bd);34       }35       end = GetTickCount ();36       cout<<"cost time:" <<end - begin<<endl ;37 }38 int main()39 {40       TestReference();41       return 0;42 }

平面設(shè)計培訓(xùn),網(wǎng)頁設(shè)計培訓(xùn),美工培訓(xùn),游戲開發(fā),動畫培訓(xùn)

 

以上代碼的運行結(jié)果為:

 

平面設(shè)計培訓(xùn),網(wǎng)頁設(shè)計培訓(xùn),美工培訓(xùn),游戲開發(fā),動畫培訓(xùn)

 

從運行結(jié)果我們不難看出相比于傳值而言,傳引用無疑極大地提升了程序的性能。

 

2.引用作為函數(shù)的返回值時

 

平面設(shè)計培訓(xùn),網(wǎng)頁設(shè)計培訓(xùn),美工培訓(xùn),游戲開發(fā),動畫培訓(xùn)

 1 int& Add (int d1, int d2) 2 { 3 int ret = d1 + d2; 4 return ret ; 5 } 6 void test() 7 { 8 int a = 3, b = 4; 9 int c = Add( a, b );10 cout<<"c:" <<c<< endl;11 }

平面設(shè)計培訓(xùn),網(wǎng)頁設(shè)計培訓(xùn),美工培訓(xùn),游戲開發(fā),動畫培訓(xùn)

 

上面這段代碼是錯誤的用法,因為用引用接收了一個局部或臨時變量的地址,在我們編譯的時候回報出如下的警告:

 

平面設(shè)計培訓(xùn),網(wǎng)頁設(shè)計培訓(xùn),美工培訓(xùn),游戲開發(fā),動畫培訓(xùn)

 

       這里是因為函數(shù)在返回的時候會創(chuàng)建一個臨時變量,而我們在以引用作為函數(shù)的返回值的時候,引用的是這個臨時變量,我們都知道臨時變量在函數(shù)運行完畢后會銷毀的,那樣這種寫法毫無疑問是錯誤的不推薦的。

而下面的代碼則是以傳值作為函數(shù)的返回值,是正確的,當(dāng)我們要以引用作為函數(shù)的返回值的時候,我們應(yīng)該return一個以引用傳遞的參數(shù),那樣也就是正確的。

平面設(shè)計培訓(xùn),網(wǎng)頁設(shè)計培訓(xùn),美工培訓(xùn),游戲開發(fā),動畫培訓(xùn)

 1 int Add1 (int a, int b) 2 { 3       int ret = a + b; 4       return ret; 5 } 6 int& Add2(int& a, int b) 7 { 8       int ret = a + b; 9       return ret;10 }11 void test1()12 {13       int ret = Add1(1, 2);14       cout<<"ret:" <<ret<< endl;15 }16 void test2()17 {18       int a = 3, b = 4;19       int c = Add2( a, b );20       cout<<"c:" <<c<< endl;21 }22 int main ()23 {24       test1();25       test2();26       return 0;27 }

平面設(shè)計培訓(xùn),網(wǎng)頁設(shè)計培訓(xùn),美工培訓(xùn),游戲開發(fā),動畫培訓(xùn)

 

我們查看上面兩個函數(shù)以傳值作為函數(shù)返回值和傳引用作為函數(shù)返回值時的匯編有何不同,如下圖:


平面設(shè)計培訓(xùn),網(wǎng)頁設(shè)計培訓(xùn),美工培訓(xùn),游戲開發(fā),動畫培訓(xùn)

 

我們不難發(fā)現(xiàn)傳值返回的時候是把ret的值放入了eax寄存器中,而傳引用返回的時候是把ret的地址放進(jìn)了eax寄存器中。

因此我們應(yīng)該在使用引用作為函數(shù)的返回值的時候應(yīng)該注意:

1.不要返回?個臨時變量的引?。
2. 如果返回對象出了當(dāng)前函數(shù)的作?域依舊存在,則最好使?引?返回,因為這樣更?效

 

在C語言中有指針,而C++中有應(yīng)用,那么指針與引用究竟有什么區(qū)別與聯(lián)系呢?

平面設(shè)計培訓(xùn),網(wǎng)頁設(shè)計培訓(xùn),美工培訓(xùn),游戲開發(fā),動畫培訓(xùn)

1. 引?只能在定義時初始化?次,之后不能改變指向其它變量(從??終);指
針變量的值可變。
2. 引?必須指向有效的變量,指針可以為空。
3. sizeof指針對象和引?對象的意義不?樣。 sizeof引?得到的是所指向的變量的
??,?sizeof指針是對象地址的??。
4. 指針和引??增(++)?減(--)意義不?樣。
5. 相對??,引??指針更安全。

平面設(shè)計培訓(xùn),網(wǎng)頁設(shè)計培訓(xùn),美工培訓(xùn),游戲開發(fā),動畫培訓(xùn)

所以在使用指針和引用的時候我們應(yīng)該知道指針雖然?引?更靈活,但是也更危險。使?指針時?定要注意檢查指針是否為空。指

針?biāo)傅牡刂丰尫乓院笞詈弥?,否則可能存在野指針問題。

http://www.cnblogs.com/kj1501120706/p/7111951.html