C++引用浅析
C++ 中,有一種比指針更加便捷的傳遞聚合類型數(shù)據(jù)的方式,那就是引用(Reference)。
在 C/C++ 中,我們將 char、int、float 等由語言本身支持的類型稱為基本類型,將數(shù)組、結(jié)構(gòu)體、類(對象)等由基本類型組合而成的類型稱為聚合類型。引用(Reference)是 C++ 相對于C語言的又一個(gè)擴(kuò)充。引用可以看做是數(shù)據(jù)的一個(gè)別名,通過這個(gè)別名和原來的名字都能夠找到這份數(shù)據(jù)。引用類似于 Windows 中的快捷方式,一個(gè)可執(zhí)行程序可以有多個(gè)快捷方式,通過這些快捷方式和可執(zhí)行程序本身都能夠運(yùn)行程序;引用還類似于人的綽號(筆名),使用綽號(筆名)和本名都能表示一個(gè)人。
引用的定義方式類似于指針,只是用&取代了*,語法格式為:
type &name = data;type 是被引用的數(shù)據(jù)的類型,name 是引用的名稱,data 是被引用的數(shù)據(jù)。引用必須在定義的同時(shí)初始化,并且以后也要從一而終,不能再引用其它數(shù)據(jù),這有點(diǎn)類似于常量(const 變量)。
引用示例:
#include <iostream> using namespace std;int main() {int a = 99;int &r = a;cout << a << ", " << r << endl;cout << &a << ", " << &r << endl;return 0; }運(yùn)行結(jié)果:
99, 99 0x28ff44, 0x28ff44變量 r 就是變量 a 的引用,它們用來指代同一份數(shù)據(jù);也可以說變量 r 是變量 a 的另一個(gè)名字。從輸出結(jié)果可以看出,a 和 r 的地址一樣,都是0x28ff44;或者說地址為0x28ff44的內(nèi)存有兩個(gè)名字,a 和 r,想要訪問該內(nèi)存上的數(shù)據(jù)時(shí),使用哪個(gè)名字都行。
注意,引用在定義時(shí)需要添加&,在使用時(shí)不能添加&,使用時(shí)添加&表示取地址。
由于引用 r 和原始變量 a 都是指向同一地址,所以通過引用也可以修改原始變量中所存儲(chǔ)的數(shù)據(jù),請看下面的例子:
#include <iostream> using namespace std;int main() {int a = 99;int &r = a;r = 47;cout << a << ", " << r << endl;return 0; }運(yùn)行結(jié)果:
47, 47最終程序輸出兩個(gè) 47,可見原始變量 a 的值已經(jīng)被引用變量 r 所修改。
如果不希望通過引用來修改原始的數(shù)據(jù),那么可以在定義時(shí)添加 const 限制,形式為:
const type &name = value;也可以是:
type const &name = value;這種引用方式為常引用
C++引用作為函數(shù)參數(shù)
在定義或聲明函數(shù)時(shí),我們可以將函數(shù)的形參指定為引用的形式,這樣在調(diào)用函數(shù)時(shí)就會(huì)將實(shí)參和形參綁定在一起,讓它們都指代同一份數(shù)據(jù)。如此一來,如果在函數(shù)體中修改了形參的數(shù)據(jù),那么實(shí)參的數(shù)據(jù)也會(huì)被修改,從而擁有“在函數(shù)內(nèi)部影響函數(shù)外部數(shù)據(jù)”的效果。
引用傳參交換兩個(gè)數(shù)的值,請看下面的代碼:
#include <iostream> using namespace std;void swap1(int a, int b); void swap2(int *p1, int *p2); void swap3(int &r1, int &r2);int main() {int num1, num2;cout << "Input two integers: ";cin >> num1 >> num2;swap1(num1, num2);cout << num1 << " " << num2 << endl;cout << "Input two integers: ";cin >> num1 >> num2;swap2(&num1, &num2);cout << num1 << " " << num2 << endl;cout << "Input two integers: ";cin >> num1 >> num2;swap3(num1, num2);cout << num1 << " " << num2 << endl;return 0; }//直接傳遞參數(shù)內(nèi)容 void swap1(int a, int b) {int temp = a;a = b;b = temp; }//傳遞指針 void swap2(int *p1, int *p2) {int temp = *p1;*p1 = *p2;*p2 = temp; }//按引用傳參 void swap3(int &r1, int &r2) {int temp = r1;r1 = r2;r2 = temp; }運(yùn)行結(jié)果:
Input two integers: 15 34 15 34 Input two integers: 81 99 99 81 Input two integers: 100 200 200 100本例演示了三種交換變量的值的方法:
1 swap1() 直接傳遞參數(shù)的內(nèi)容,不能達(dá)到交換兩個(gè)數(shù)的值的目的。對于 swap1() 來說,a、b 是形參,是作用范圍僅限于函數(shù)內(nèi)部的局部變量,它們有自己獨(dú)立的內(nèi)存,和 num1、num2 指代的數(shù)據(jù)不一樣。調(diào)用函數(shù)時(shí)分別將 num1、num2 的值傳遞給 a、b,此后 num1、num2 和 a、b 再無任何關(guān)系,在 swap1() 內(nèi)部修改 a、b 的值不會(huì)影響函數(shù)外部的 num1、num2,更不會(huì)改變 num1、num2 的值。
2 swap2() 傳遞的是指針,能夠達(dá)到交換兩個(gè)數(shù)的值的目的。調(diào)用函數(shù)時(shí),分別將 num1、num2 的指針傳遞給 p1、p2,此后 p1、p2 指向 a、b 所代表的數(shù)據(jù),在函數(shù)內(nèi)部可以通過指針間接地修改 a、b 的值。
3 swap3() 是按引用傳遞,能夠達(dá)到交換兩個(gè)數(shù)的值的目的。調(diào)用函數(shù)時(shí),分別將 r1、r2 綁定到 num1、num2 所指代的數(shù)據(jù),此后 r1 和 num1、r2 和 num2 就都代表同一份數(shù)據(jù)了,通過 r1 修改數(shù)據(jù)后會(huì)影響 num1,通過 r2 修改數(shù)據(jù)后也會(huì)影響 num2。
我們可以發(fā)現(xiàn),按引用傳參在使用形式上比指針更加直觀。推薦大家使用使用引用,它一般可以代替指針(當(dāng)然指針在C++中也不可或缺),C++ 標(biāo)準(zhǔn)庫也是這樣做的。
C++引用作為函數(shù)返回值
引用除了可以作為函數(shù)形參,還可以作為函數(shù)返回值,請看下面的例子:
#include <iostream> using namespace std;int &plus10(int &r) {r += 10;return r; }int main() {int num1 = 10;int num2 = plus10(num1);cout << num1 << " " << num2 << endl;return 0; }運(yùn)行結(jié)果:
20 20在將引用作為函數(shù)返回值時(shí)應(yīng)該注意一個(gè)小問題,就是不能返回局部數(shù)據(jù)(例如局部變量、局部對象、局部數(shù)組等)的引用,因?yàn)楫?dāng)函數(shù)調(diào)用完成后局部數(shù)據(jù)就會(huì)被銷毀,有可能在下次使用時(shí)數(shù)據(jù)就不存在了,C++ 編譯器檢測到該行為時(shí)也會(huì)給出警告。
總結(jié)
- 上一篇: Java 文件重命名
- 下一篇: C++ 容器适配器