1、const 引用是指向 const 對(duì)象的引用:
const int ival = 1024;
const int &refVal = ival; // ok: both reference and object are const
int &ref2 = ival; // error: non const reference to a const object
可以讀取但不能修改 refVal。同理,用 ival 初始化 ref2 也是不合法的。ref2 是普通的非 const 引用,因此可以用來(lái)修改 ref2 指向的對(duì)象的值。通過(guò) ref2 對(duì) ival 賦值會(huì)導(dǎo)致修改 const 對(duì)象的值。為阻止這樣的修改,需要規(guī)定將普通的引用綁定到 const 對(duì)象是不合法的。
const 引用可以初始化為不同類型的對(duì)象或者初始化為右值,如字面值常量:
int i = 42;
// legal for const references only
const int &r = 42;
const int &r2 = r + i;
同樣的初始化對(duì)于非 const 引用卻是不合法的,而且會(huì)導(dǎo)致編譯時(shí)錯(cuò)誤。
即:非 const 引用只能綁定到與該引用同類型的對(duì)象。而const 引用則可以綁定到不同但相關(guān)的類型的對(duì)象或綁定到右值。
2、每種容器類型定義了一種名為 const_iterator 的類型,該類型只能用于讀取容器內(nèi)元素,但不能改變其值。即使用 const_iterator 類型時(shí),我們可以得到一個(gè)迭代器,它自身的值可以改變,但不能用來(lái)改變其所指向的元素的值??梢詫?duì)迭代器進(jìn)行自增以及使用解引用操作符來(lái)讀取值,但不能對(duì)該元素賦值。
例如,如果text是vector 類型,程序員想要遍歷它,輸出每個(gè)元素,可以這樣編寫(xiě)程序:
// use const_iterator because we won't change the elements
for (vector::const_iterator iter = text.begin();iter != text.end(); ++iter)
cout << *iter << endl; // print each element in text
除了是從迭代器讀取元素值而不是對(duì)它進(jìn)行賦值之外,這個(gè)循環(huán)與普通循環(huán)相似。由于這里只需要借助迭代器進(jìn)行讀,不需要寫(xiě),這里把iter 定義為const_iterator 類型。當(dāng)對(duì)const_iterator 類型解引用時(shí),返回的是一個(gè)const 值。不允許用const_iterator進(jìn)行賦值
for (vector::const_iterator iter = text.begin();iter != text.end(); ++ iter)
*iter = " "; // error: *iter is const
總而言之:使用const_iterator類型時(shí),我們可以得到一個(gè)迭代器,它自身的值可以改變,但不能用來(lái)改變其所指向的元素的值。可以對(duì)迭代器進(jìn)行自增以及使用解引用操作符來(lái)讀取值,但不能對(duì)該元素賦值。
3、不要把const_iterator對(duì)象與const的iterator對(duì)象混淆起來(lái)。聲明一個(gè)const迭代器時(shí),必須初始化迭代器。一旦被初始化后,就不能改變它的值:
vector nums(10); // nums is nonconst
const vector::iterator cit = nums.begin();
*cit = 1; // ok: cit can change its underlying element
++cit; // error: can't change the value of cit
即:// an iterator that cannot write elements
vector::const_iterator
// an iterator whose value cannot change
const vector::iterator
4、指向 const 對(duì)象的指針
如果指針指向const對(duì)象,則不允許用指針來(lái)改變其所指的const值。為了保證這個(gè)特性C++語(yǔ)言強(qiáng)制要求指向const對(duì)象的指針也必須具有const特性:
const double *cptr; // cptr may point to a double that is const
這里的cptr是一個(gè)指向double類型const對(duì)象的指針,const限定了cptr指針?biāo)赶虻膶?duì)象類型,而并非cptr本身。也就是說(shuō),cptr本身并不是const。在定義時(shí)不需要對(duì)它進(jìn)行初始化,如果需要的話,允許給 cptr重新賦值,使其指向另一個(gè)const對(duì)象。但不能通過(guò)cptr修改其所指對(duì)象的值:
*cptr = 42; // error: *cptr might be const
把一個(gè) const 對(duì)象的地址賦給一個(gè)普通的、非 const 對(duì)象的指針也會(huì)導(dǎo)致編譯時(shí)的錯(cuò)誤:
const double pi = 3.14;
double *ptr = π // error: ptr is a plain pointer
const double *cptr = π // ok: cptr is a pointer to const
允許把非 const 對(duì)象的地址賦給指向 const 對(duì)象的指針,例如:
double dval = 3.14; // dval is a double; its value can be changed
cptr = &dval; // ok: but can't change dval through cptr
盡管dval不是const對(duì)象,但任何企圖通過(guò)指針cptr修改其值的行為都會(huì)導(dǎo)致編譯時(shí)的錯(cuò)誤。cptr一經(jīng)定義,就不允許修改其所指對(duì)象的值。如果該指針恰好指向非const對(duì)象時(shí),同樣必須遵循這個(gè)規(guī)則。
在實(shí)際的程序中,指向 const 的指針常用作函數(shù)的形參。將形參定義為指向 const 的指針,以此確保傳遞給函數(shù)的實(shí)際對(duì)象在函數(shù)中不因?yàn)樾螀⒍恍薷摹?BR> 5、const 指針
除指向 const 對(duì)象的指針外,C++ 語(yǔ)言還提供了 const 指針——本身的值不能修改:
int errNumb = 0;
int *const curErr = &errNumb; // curErr is a constant pointer
我們可以從右向左把上述定義語(yǔ)句讀作“curErr 是指向 int 型對(duì)象的 const 指針”。與其他 const 量一樣,const 指針的值不能修改,這就意味著不能使 curErr 指向其他對(duì)象。任何企圖給 const 指針賦值的行為(即使給 curErr 賦回同樣的值)都會(huì)導(dǎo)致編譯時(shí)的錯(cuò)誤:
curErr = curErr; // error: curErr is const
與任何 const 量一樣,const 指針也必須在定義時(shí)初始化。
指針本身是 const 的事實(shí)并沒(méi)有說(shuō)明是否能使用該指針修改它所指向?qū)ο蟮闹怠?荚?大提示指針?biāo)笇?duì)象的值能否修改完全取決于該對(duì)象的類型。例如,curErr 指向一個(gè)普通的非常量 int 型對(duì)象 errNumb,則可使用 curErr 修改該對(duì)象的值:
if (*curErr) {
errorHandler();
*curErr = 0; // ok: reset value of the object to which curErr is bound
}
6、指向 const 對(duì)象的 const 指針
還可以如下定義指向 const 對(duì)象的 const 指針:
const double pi = 3.14159;
// pi_ptr is const and points to a const object
const double *const pi_ptr = π
本例中,既不能修改 pi_ptr 所指向?qū)ο蟮闹?,也不允許修改該指針的指向(即 pi_ptr 中存放的地址值)。可從右向左閱讀上述聲明語(yǔ)句:“pi_ptr 首先是一個(gè) const 指針,指向 double 類型的 const 對(duì)象”。
const int ival = 1024;
const int &refVal = ival; // ok: both reference and object are const
int &ref2 = ival; // error: non const reference to a const object
可以讀取但不能修改 refVal。同理,用 ival 初始化 ref2 也是不合法的。ref2 是普通的非 const 引用,因此可以用來(lái)修改 ref2 指向的對(duì)象的值。通過(guò) ref2 對(duì) ival 賦值會(huì)導(dǎo)致修改 const 對(duì)象的值。為阻止這樣的修改,需要規(guī)定將普通的引用綁定到 const 對(duì)象是不合法的。
const 引用可以初始化為不同類型的對(duì)象或者初始化為右值,如字面值常量:
int i = 42;
// legal for const references only
const int &r = 42;
const int &r2 = r + i;
同樣的初始化對(duì)于非 const 引用卻是不合法的,而且會(huì)導(dǎo)致編譯時(shí)錯(cuò)誤。
即:非 const 引用只能綁定到與該引用同類型的對(duì)象。而const 引用則可以綁定到不同但相關(guān)的類型的對(duì)象或綁定到右值。
2、每種容器類型定義了一種名為 const_iterator 的類型,該類型只能用于讀取容器內(nèi)元素,但不能改變其值。即使用 const_iterator 類型時(shí),我們可以得到一個(gè)迭代器,它自身的值可以改變,但不能用來(lái)改變其所指向的元素的值??梢詫?duì)迭代器進(jìn)行自增以及使用解引用操作符來(lái)讀取值,但不能對(duì)該元素賦值。
例如,如果text是vector
// use const_iterator because we won't change the elements
for (vector
cout << *iter << endl; // print each element in text
除了是從迭代器讀取元素值而不是對(duì)它進(jìn)行賦值之外,這個(gè)循環(huán)與普通循環(huán)相似。由于這里只需要借助迭代器進(jìn)行讀,不需要寫(xiě),這里把iter 定義為const_iterator 類型。當(dāng)對(duì)const_iterator 類型解引用時(shí),返回的是一個(gè)const 值。不允許用const_iterator進(jìn)行賦值
for (vector
*iter = " "; // error: *iter is const
總而言之:使用const_iterator類型時(shí),我們可以得到一個(gè)迭代器,它自身的值可以改變,但不能用來(lái)改變其所指向的元素的值。可以對(duì)迭代器進(jìn)行自增以及使用解引用操作符來(lái)讀取值,但不能對(duì)該元素賦值。
3、不要把const_iterator對(duì)象與const的iterator對(duì)象混淆起來(lái)。聲明一個(gè)const迭代器時(shí),必須初始化迭代器。一旦被初始化后,就不能改變它的值:
vector
const vector
*cit = 1; // ok: cit can change its underlying element
++cit; // error: can't change the value of cit
即:// an iterator that cannot write elements
vector
// an iterator whose value cannot change
const vector
4、指向 const 對(duì)象的指針
如果指針指向const對(duì)象,則不允許用指針來(lái)改變其所指的const值。為了保證這個(gè)特性C++語(yǔ)言強(qiáng)制要求指向const對(duì)象的指針也必須具有const特性:
const double *cptr; // cptr may point to a double that is const
這里的cptr是一個(gè)指向double類型const對(duì)象的指針,const限定了cptr指針?biāo)赶虻膶?duì)象類型,而并非cptr本身。也就是說(shuō),cptr本身并不是const。在定義時(shí)不需要對(duì)它進(jìn)行初始化,如果需要的話,允許給 cptr重新賦值,使其指向另一個(gè)const對(duì)象。但不能通過(guò)cptr修改其所指對(duì)象的值:
*cptr = 42; // error: *cptr might be const
把一個(gè) const 對(duì)象的地址賦給一個(gè)普通的、非 const 對(duì)象的指針也會(huì)導(dǎo)致編譯時(shí)的錯(cuò)誤:
const double pi = 3.14;
double *ptr = π // error: ptr is a plain pointer
const double *cptr = π // ok: cptr is a pointer to const
允許把非 const 對(duì)象的地址賦給指向 const 對(duì)象的指針,例如:
double dval = 3.14; // dval is a double; its value can be changed
cptr = &dval; // ok: but can't change dval through cptr
盡管dval不是const對(duì)象,但任何企圖通過(guò)指針cptr修改其值的行為都會(huì)導(dǎo)致編譯時(shí)的錯(cuò)誤。cptr一經(jīng)定義,就不允許修改其所指對(duì)象的值。如果該指針恰好指向非const對(duì)象時(shí),同樣必須遵循這個(gè)規(guī)則。
在實(shí)際的程序中,指向 const 的指針常用作函數(shù)的形參。將形參定義為指向 const 的指針,以此確保傳遞給函數(shù)的實(shí)際對(duì)象在函數(shù)中不因?yàn)樾螀⒍恍薷摹?BR> 5、const 指針
除指向 const 對(duì)象的指針外,C++ 語(yǔ)言還提供了 const 指針——本身的值不能修改:
int errNumb = 0;
int *const curErr = &errNumb; // curErr is a constant pointer
我們可以從右向左把上述定義語(yǔ)句讀作“curErr 是指向 int 型對(duì)象的 const 指針”。與其他 const 量一樣,const 指針的值不能修改,這就意味著不能使 curErr 指向其他對(duì)象。任何企圖給 const 指針賦值的行為(即使給 curErr 賦回同樣的值)都會(huì)導(dǎo)致編譯時(shí)的錯(cuò)誤:
curErr = curErr; // error: curErr is const
與任何 const 量一樣,const 指針也必須在定義時(shí)初始化。
指針本身是 const 的事實(shí)并沒(méi)有說(shuō)明是否能使用該指針修改它所指向?qū)ο蟮闹怠?荚?大提示指針?biāo)笇?duì)象的值能否修改完全取決于該對(duì)象的類型。例如,curErr 指向一個(gè)普通的非常量 int 型對(duì)象 errNumb,則可使用 curErr 修改該對(duì)象的值:
if (*curErr) {
errorHandler();
*curErr = 0; // ok: reset value of the object to which curErr is bound
}
6、指向 const 對(duì)象的 const 指針
還可以如下定義指向 const 對(duì)象的 const 指針:
const double pi = 3.14159;
// pi_ptr is const and points to a const object
const double *const pi_ptr = π
本例中,既不能修改 pi_ptr 所指向?qū)ο蟮闹?,也不允許修改該指針的指向(即 pi_ptr 中存放的地址值)。可從右向左閱讀上述聲明語(yǔ)句:“pi_ptr 首先是一個(gè) const 指針,指向 double 類型的 const 對(duì)象”。