C++引用的用法

什麼是引用?

       引用就是某一變量或者某一目標的別名。對引用的操作就是對實際變量的操作。引用的聲明方式:類型標識符 &引用名=目標變量名。

    (1)&在此不是求地址運算,而是起標識作用。
    (2)類型標識符是指目標變量的類型。
    (3)聲明引用時,必須同時對其進行初始化。
    (4)引用聲明完畢後,相當於目標變量名有兩個名稱,即該目標原名稱和引用名,且不能再把該引用名作爲其他變量名的別名。
       int a,&ra=a;
       a爲目標原名稱,ra爲目標引用名。給ra賦值:ra=1; 等價於 a=1;
    (5)對引用求地址,就是對目標變量求地址。&ra與&a相等。即我們常說引用名是目標變量名的一個別名。別名一詞好像是說引用不佔據任何內存空間。但是編譯器在一般將其實現爲const指針,即指向位置不可變的指針。即引用實際上與一般指針同樣佔用內存。
    (6)不能建立引用的數組。因爲數組是一個由若干個元素所組成的集合,所以無法建立一個由引用組成的集合。但是可以建立數組的引用.
例如: int& ref [3]= {2,3,5};//聲明ref引用的數組錯誤
但是可以這樣寫:
const int (&ref)[3] ={2,3,5};
爲什麼要加上const ,因爲{2,3,5}此時是個字面值數組,是保存在代碼段裏,只讀的屬性,如果不加,編譯錯誤,而且後面對ref[0]的賦值也不會成功.
需要特別強調的是引用並不產生對象的副本,僅僅是對象的同義詞。
     (7)引用必須在定義時馬上被初始化,因爲它必須是某個東西的同義詞。你不能先定義一個引用後才
初始化它。例如下面語句是非法的:
Point &pt3;
pt3=pt1;
     (8)引用是除指針外另一個可以產生多態效果的手段。
這意味着,一個基類的引用可以指向它的派生類實例。例如:

class A;
class B: public A
{
   ...
};

B b;
A & aRef = b;    // 基類引用指向派生類

如果A類中定義有虛函數,並且在B類中重寫了這個虛函數,就可以通過aRef產生多態效果。

 
下面是引用的使用例子,說明都在代碼註釋裏了。
#include <iostream>
using namespace std;
void swap1(int a,int b);
void swap2(int* a,int* b);
void swap3(int& a,int& b);
void swap4(const char* a,const char* b);
void swap5(const char** a,const char** b);
void swap6(const char*& a,const char*& b);

int main()
{
	int a = 10,b = 20;
	swap1(a,b);
	cout<<"swap1"<<" : "<<a<<" , "<<b<<endl;	//輸出10,20;
	swap2(&a,&b);
	cout<<"swap2"<<" : "<<a<<" , "<<b<<endl;	//20,10
	swap3(a,b);
	cout<<"swap3"<<" : "<<a<<" , "<<b<<endl;	//10,20 因爲swap2已經交換了;

	const char* pa = "hello";
	const char* pb = "world";
	swap4(pa,pb);
	cout<<"swap4"<<" : "<<pa<<" , "<<pb<<endl;	//hello,world;
	swap5(&pa,&pb);
	cout<<"swap5"<<" : "<<pa<<" , "<<pb<<endl;	//world,hello;
	swap6(pa,pb);
	cout<<"swap6"<<" : "<<pa<<" , "<<pb<<endl;	//world,hello;

	system("pause");
	return 0;
}

//值傳遞,只是形參的交換,並沒有實現實參的交換;
void swap1(int a,int b)
{
	int c = a;
	a = b;
	b = c;
}

//形參指向的是實參的地址,直接對實參地址內容的交換就是實參值的交換;
void swap2(int* a,int* b)
{
	int c = *a;
	*a = *b;
	*b = c;
}

//引用交換,形參引用就是實參的別名,引用實質是指針,看上去交換的是形參的值,實際上交換的就是實參;
void swap3(int& a,int& b)
{
	int c = a;
	a = b;
	b = c;
}

//因爲實參本身就是指針,所以仍然是值傳遞,並沒有對實參的地址交換;
void swap4(const char* a,const char* b)
{
	const char* c = a;
	a = b;
	b = c;
}

//傳遞實參的地址,完成實參值的交換;
void swap5(const char** a,const char** b)
{
	const char* c = *a;
	*a = *b;
	*b = c;
}

//使用指針的引用,實際上交換的就是實參;
void swap6(const char*& a,const char*& b)
{
	const char* c = a;
	a = b;
	b = c;
}

//判斷指針和引用的時候,需要從右向左讀 例如 char ** a 則 a 是一個指針,指向另一個指針,而另一個指針指向的是char;
//const char*& b 則 b 是一個引用,是一個指針的引用,而指針指向的是一個 const char;


//引用的作用一般是爲了節約效率,例如函數傳遞的參數是結構體,或者類,那麼如果進行值傳遞,性能就比較低;
//但是需要注意的是,引用一般搭配const類型一起使用。因爲這樣可以避免在參數傳遞時,由於程序員的失誤導致的實參值篡改;


//另外,引用還被用於函數的輸出參數;
//指針方式;
double calcircle1(double r,double* area)
{
	*area = 3.14 * r * r;	//圓的面積;
	return 2 * 3.14 * r;	//圓的周長;
}
//調用方式;
double area;
double c = calcircle1(3,&area);

//引用方式;
double calcircle2(double r,double& area)
{
	area = 3.14 * r * r;	//圓的面積;
	return 2 * 3.14 * r;	//圓的周長;
}

//調用方式;
double area;
double c = calcircle2(3,area);

 

 

發佈了21 篇原創文章 · 獲贊 6 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章