1. 程式人生 > >C++中const與引用,指標之間的關係要點

C++中const與引用,指標之間的關係要點

一、const關鍵字
1、有時我們希望定義這樣的一個變數,它的值不能被改變。這時就可以在定義變數時加上const關鍵字。例如

const int bufSize=512;

const型別變數可以進行大部分與非const型別變數相同操作,主要的限制就是不可以在const型別的物件上執行任何改變其內容的操作。(因為const型別物件一旦建立後其值就不可以再改變,所以必須初始化,關於不同情況下的初始化下面會詳細說明)
2、預設情況下,const物件只在定義它的檔案內有效,要是想在其他檔案中也可以使用,那麼對於const變數不管是宣告還是定義都應該加上extern關鍵字。

extern
const int bufSize=512;

以後編譯器會找到程式碼中所有用到bufSize的地方,並把它替換成512。所以const關鍵字類似於C語言裡的巨集定義的功能。

二、單純const物件的初始化
1、

int i=42;
const int c=i; //可以用非const物件給const物件初始化 

2、

const int c=10;
int j=c;    //可以用const物件給非const變數初始化

總結就是如果用一個物件去初始化另一個物件的時候,是不是const物件都無關緊要。

三、const的引用
1、當把const和引用繫結在一起的時候,稱作是對常量的引用(常量引用),對常量的引用不可以修改他所繫結的物件,如下例:

const int c=1024;
const int &r=c;
r=1000;   //錯誤,因為此時r是c的引用(也就是c的別名,因為是常量引用,所以不可以通過r來改變c的值,但是c的值本身是否可以通過別的方式來改變要看C本身,這裡C是常量,所以也不可以通過別的方式來改變)

2、關於“對常量的引用”的初始化
(1)在初始化常量引用時允許使用任意型別表示式作為初始值,只要該表示式最終可以轉換成引用的型別即可。例如:

int i=42;
const int &r1=i;
const int &r2=42;
const int &r3=r1*2;
//上訴程式碼都是正確的(注意:此時不可以通過r1,r2,r3來改變所引用物件得值,但是由於i非常量,所以i的值可以任意被改變)

(2)在引用一個常量的時候必須是常量引用,不可以是一般的普通引用。例如:

const int i=42;
const int &r1=i;   //正確(注意此時既不可以通過r1來改變i的值,這點與(1)情況一樣,也不可以通過其他方式改變i的值,因為i是常量)
int &r2=i;        //錯誤

總結
就是對一個常量引用進行初始化可以任意型別表示式(const非const都可以),此時不可以通過引用來改變他所繫結的物件,但是被繫結的物件可不可以通過其他方式來進行改變則需要看被繫結的物件自身,如果自身是const型別,則不可以;如果自身不是const型別,則可以通過其他方式來改變。
對常量(const物件)進行引用則必須是常量引用。且不可以通過引用來改變被繫結物件的值,同樣被繫結的物件的值也不可以通過其他方式來改變。

四、指標和const
1、int const *p與const int * p等價(只要const在 * 左面)就叫做指向常量的指標。
指向常量的指標和常量引用類似。指向常量的指標的初始化可以是任意型別的物件(可以指向任意型別的物件),但是不可以通過指標來改變所指向物件的值,被指向的物件的值可不可以通過其他方式被改變,要看被指向的物件本身。例如:

double p=3.14;
const double pi=3.14;
const double *ptr=&p;  //正確,可以用指向常量的指標指向一個非const變數,(但是此時不可以用*ptr的方式改變p的值,但是p的值可以通過其他方式來改變)
const double *ptr=π//正確,可以用指向常量的指標指向一個const變數,(此時既不可以用*ptr的方式來改變pi的值,也不可以用其他方式來改變pi的值,因為pi是const常量)
double *pt=π//不可以,因為要想存放常量物件的地址,只可以是指向常量的指標。

注意:指向常量的指標雖然不可以改變其指向物件的值,但是卻可以改變指標的指向,即在指標存在範圍內,可以指向多個不同的物件。(這一點與下面要說的常量指標不同)
2、常量指標
(1)所謂常量指標就是把指標變成常量,不可以改變(既常量指標初始化後,他的指向就不可以變)常量指標必須初始化。把*號放在const前面就意味著這個指標是常量。如下:

int a=0int *const p=&a;//正確,此時可以利用*p來改變a的值,但是p將一直指向a,不可以指向其他。
const int b=1;
int *const q=&b;//不可以,因為b是常量,所以必須要用指向常量的指標(即const在*前面)來指向b,具體見下面
const int * const q=&b;//正確。q是一個指向常量物件的指標常量。(小技巧:分析一個變數型別時,從右往左讀,越靠近變數的越能決定一個變數的性質。最靠近的是q的是const,說明q是一個常量,又是*說明是一個常量指標,然後是int,說明這個指標指向一個int型變數,然後是const,說明這是一個指向常量物件的常量指標)在這裡,不可以用*p改變b的值,p也不可以指向其他的物件,b也不可以通過其他方式改變值。

總結常量指標初始化後不可以指向別的物件,但是是否可以通過常量指標來改變物件的值要看被指向的物件是否是常量。