[003]Reference in C++---C++引用基础知识篇
最近在搞C++的引用,閑來無事,順便寫寫引用的基礎知識
引言:什么是引用
? 引用就是某一變量(目標)的一個別名,對引用的操作與對變量直接操作完全一樣。
引用的格式:
? 數據類型 &引用變量名 = 目標變量名;
第一章 引用的一些基本語法
(1)&在此不是求地址運算,而是起標識作用。
(2)類型標識符是指目標變量的類型。
(3)聲明引用時,必須同時對其進行初始化。
(4)引用聲明完畢后,相當于目標變量名有兩個名稱,即該目標原名稱和引用名,且不能再把該引用名作為其他變量名的別名。
(5)聲明一個引用,不是新定義了一個變量,它只表示該引用名是目標變量名的一個別名,它本身不是一種數據類型,因此引用本身不占存儲單元,系統也不給引用分配存儲單元。故:對引用求地址,就是對目標變量求地址。
(6)不能建立數組的引用。因為數組是一個由若干個元素所組成的集合,所以無法建立一個數組的別名。
第二章 引用的應用
1、作為函數的傳遞參數
例:
View Code 1 #include <iostream>2 using namespace std;3 4 void foo(int &a, int &b)5 {6 int c = 0;7 c = a + b;8 cout << c <<endl;9 } 10 int main() 11 { 12 int x = 1; 13 int y = 2; 14 foo(x, y); 15 16 system("pause"); 17 return 0; 18 }其效果與值傳遞是一樣的,被調函數的形參就成為原來主調函數中的實參變量或對象的一個別名來使用,所以在被調函數中對形參變量的操作就是對其相應的目標對象(在主調函數中)的操作。但需要注意的是:
①使用引用傳遞函數的參數,在內存中并沒有產生實參的副本,它是直接對實參操作。這樣做的好處在于:有大塊數據作為參數傳遞的時候,可以避免將整塊數據全部壓棧,可以提高程序的效率;
②要達到這種效果,使用指針傳遞也是一樣的,但是在閱讀性上,還是不如引用的,因為指針這個東東,出錯的概率很高>_<!
比如,這個就很不好看
View Code 1 #include <iostream>2 using namespace std;3 4 void foo(int *a, int *b)5 {6 int c = 0;7 c = *a + *b;8 cout << c <<endl;9 } 10 int main() 11 { 12 int x = 1; 13 int y = 2; 14 foo(&x, &y); 15 16 system("pause"); 17 return 0; 18 }2、常量引用
? 事先需要說明一點:引用是不能直接來常量引用的,比如:int &a = 1;就是一個錯誤的語句。
? 但是我們可以通過const來實現常量引用,上面的語句,我們可以改為:const int &a = 1;
? 需要注意的是:這種方式的聲明,不能通過引用對引用變量進行修改,但是可以對目標變量名進行修正來達到目的:
View Code #include <iostream> using namespace std;void foo(int *a, int *b) {int c = 0;c = *a + *b;cout << c <<endl; } int main() {int x = 1;int y = 2;foo(&x, &y);int z = 2;const int &a =z;//a = 5; wrong!z = 4;cout << a << '\n' <<endl;system("pause");return 0; }輸出結果為:
3 43、引用作為返回值
? 函數聲明格式:類型標識符 &函數名(形參列表及類型說明);
? 這種使用方法的好處在于,在內存中不產生被返回值的副本(即臨時變量),例如:
View Code? 使用引用作為返回值時,還需要注意以下幾點:
①不能返回局部變量的引用。因為局部變量會在函數返回后被銷毀,因此被返回的引用就成為了"無所指"的引用,程序會進入未知狀態。
②不能返回函數內部new分配的內存的引用。雖然不存在局部變量的被動銷毀問題,可對于這種情況(返回函數內部new分配內存的引用),又面臨其它尷尬局面。例如,被函數返回的引用只是作為一個臨時變量出現,而沒有被賦予一個實際的變量,那么這個引用所指向的空間(由new分配)就無法釋放,造成memory leak。
③可以返回類成員的引用,但最好是const。
4、引用和多態
? 產生這個問題的根本來源就在于:一個基類的引用可以指向它的派生類實例。這就很容易產生一個問題:引用也會產生多態效果。
? 例:
View Code 1 #include <iostream>2 using namespace std;3 4 class A {5 public:6 A();7 virtual void foo() {8 cout << "a" << endl;9 }; 10 }; 11 12 A::A() { 13 } 14 15 class B: public A { 16 public: 17 void foo1() { 18 cout << "b" << endl; 19 }; 20 }; 21 22 int main() 23 { 24 B b; 25 A &a = b; 26 a.foo(); // 訪問派生類對象中從基類繼承下來的成員 27 // a.foo1(); // wrong! 28 b.foo(); 29 b.foo1(); 30 system("pause"); 31 return 0; 32 }第三章 引用和指針
不同點:
? ①初始化:引用必須在創建的時候就初始化,但是指針可以在任何時候被初始化
? ②引用不能為空,但是指針可以為NULL
? ③引用的對象被初始化后就無法更改,但是指針指向的對象是可以更改的
? ④內存:引用與被引用對象共享內存空間,系統不會為引用變量分配內存空間,但系統會為指針分配內存空間
? ⑤在作為形參傳遞的時候,引用不拷貝副本,指針拷貝副本
? ⑥引用訪問的對象是直接訪問,而指針是間接訪問
?關系:
? 引用的實現,在內部來看,其實就是用指針來實現的,可以來看一個指針和指針的引用的例子:
View Code 1 #include <iostream> 2 using namespace std; 3 4 void foo(int *&x) { 5 *x = 100; 6 } 7 8 int main() { 9 int *x; 10 x = (int *)malloc(sizeof(int)); 11 *x=300; 12 foo(x); 13 //foo(*x);// wrong cannot convert parameter 1 from 'int ' to 'int *& ' 14 //foo(&x);//cannot convert parameter 1 from 'int **' to 'int *& ' 15 cout << "*x = " << *x <<endl; 16 17 system("pause"); 18 return 0; 19 }從上面的例子我們可以看到,其實指針的引用本質上就是雙指針。foo(*&x);這個函數也是可以編譯通過得到結果的。
?
轉載于:https://www.cnblogs.com/hustcser/archive/2013/01/02/2841992.html
總結
以上是生活随笔為你收集整理的[003]Reference in C++---C++引用基础知识篇的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MVC3使用
- 下一篇: s3c2440移植MQTT