對於C++中的const用法的總結

C++中由於有指針的存在,所以const的限定就不僅僅是對於一個普通變量的值的限定了。個人總結如下:

const int bufSize = 1024;

上述語句是定義了一個int類型的變量bufSize,並且bufSize的值固定爲1024,不能改變了。

對於一個非const變量,假設已經做了合適的聲明,就可以在另外的文件中使用這個變量,代碼來自C++ Primer中文版第四版:

//file_1.cc
int counter;//definition
//file_2.cc
extern int counter;//uses counter from file_1
++counter;//increments counter defined in file_1.cc


與其他變量不同,在全局作用域中聲明的const變量是定義該對象的文件的局部變量。此變量只存在於那個文件中,不能被其他文件訪問。

通過制定const變量爲extern,就可以在整個程序中訪問const對象:

//file_1.cc
extern const int bufSize = fcn();//definition
//file_2.cc
extern const int bufSize;//uses bufSize from file_1
for(int index=0;index !=bufSize;++index)
//...


下面討論const在引用(reference)中的應用。

const引用時指向const對象的引用:

const int ival = 1024;
const int &refVal = ival;
int &ref2 = ival;//error


上述寫法第三行是錯誤的,一個非const引用不能引用一個const的對象。

const引用可以初始化爲不同類型的對象或者初始化爲右值:

int i=42;
const int &r =42;
const int &r2 = r + i;

同樣的初始化對於非const引用卻不是合法的,而且會導致編譯時的錯誤。下面解釋一下:

double dval = 3.14;
const int &ri = dval;

編譯器會將上述代碼轉換爲以下形式:

int temp = dval;
const int &ri = temp;

如果ri不是const的,那麼可以修改ri的值,也就是你可能期待的修改dval的值,但是事實上dval並沒有被修改,只有temp的值被修改了。所以僅允許const引用綁定到需要臨時使用的值完全避免了這個問題,因爲const給予了只讀的特性。

接下來看看指針和const之間的一些特性。

指向const對象的指針,以一個例子來說明:

const double* cptr;

這裏的cptr指向了一個double類型的const對象,這個對象的值不能被改變,這裏的const只是限定了cptr所指向的對象,並沒有限定cptr本身。也就是說,可以給cptr重新賦值,讓它指向另外一個double類型的const對象。但是不能通過cptr修改所指向對象的值。

*cptr = 9;


這種寫法就是錯誤的!

不能使用void*指針保存const對象的地址,而必須使用const void*來保存:

const int i = 42;
const void *cpv = &i;
void *pp = &i;//error

上面的第三行寫法就是錯誤的!

允許把非const對象的地址賦值給指向const對象的指針,所以指向const的指針所指向的對象的值不是一定不能被修改!這句話很繞,來個例子說明:

double p = 9.0;
const double* cp = &p;

上面cp,從字面理解是不能通過它修改它指向的p的值,但是可以通過其他的方式修改p的值,例如:p=0.0;


const指針,本身的值不能被修改。

int i=0;
int *const p = &i;

雖然指針本身不能被修改,也就是:不能指向其他對象。但是指針指向的對象的值是否能被修改就沒有確定。因爲指針所指向對象的值是否能被修改取決於指針的類型前面是否有const。

const double pi = 3.14;
const double *const pip= pi;

上面的pip就是自身不能改變,並且所指向的對象的值也不能被改變。

下面看一個非常經典的問題:

typedef string *pstring;
const pstring cstr;

請問cstr是什麼類型的變量?

如果你以爲是:const string* cstr;那就錯了!

錯誤的原因在於:將typedef當做文本擴展了。聲明const pstring的時候,const修飾的是pstring類型,而pstring是一個指針,所以應該相當於:

string *const cstr;

如果還沒弄清楚的話,我覺得可以類比:

const pstring cstr;與const int ex;對比,後者表示ex的值不能被修改,前者也是一樣,表明cstr的值不能被修改,由於pstring是指針,而如果指針的值不能被修改,就應該是const放在指針類型的後面,也即:string *const cstr;

目前就總結到這裏,大部分都來源於c++ primer 第四版,然後加上一些自己的理解。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章