const關(guān)鍵字是用來(lái)修飾一個(gè)變量使其成為常量(constant)的。常量只能在定義時(shí)進(jìn)行初始化,而此后對(duì)這個(gè)變量的任何改變都將是非法的。const關(guān)鍵字在就是為了保證了它修飾的對(duì)象不被修改。
對(duì)于指針來(lái)說(shuō),const關(guān)鍵字同樣可以保證它修飾的對(duì)象不被修改,但是與一般的對(duì)象有所不同,const可以指定指針本身為常量,也可以指定指針?biāo)傅膶?duì)象為常量,亦或兼而有之。咱們看看下面這個(gè)例子:
char* p = "Hello" //#1
char* const p = "Hello" //const修飾指針p,#2
const char* p = "Hello" //const修飾指針?biāo)赶虻膬?nèi)存, #3
const char* const p = "Hello" //const同時(shí)修飾指針以及所指內(nèi)存 #4
想理解上面的4個(gè)例子,最關(guān)鍵,是要理解const的作用對(duì)象是什么。
#1,無(wú)論修改p還是*p都沒(méi)有問(wèn)題;
#2,可以修改*p,但不能修改已經(jīng)被定義為常量的p,這相當(dāng)于一個(gè)引用;
#3,const修飾指針p所指向的內(nèi)存,所以指針可以修改,而這塊內(nèi)存不能修改;
#4,這是一種極端情況,一般來(lái)說(shuō),在編程中很少用到,它就相當(dāng)于一個(gè)const的引用。
const還在函數(shù)的聲明中體現(xiàn)出強(qiáng)大的功能。它可以指定一個(gè)函數(shù)的返回值,或者函數(shù)的參數(shù);而對(duì)于類(lèi)的成員函數(shù),const還可以修飾其訪(fǎng)問(wèn)權(quán)限。
我們來(lái)看一個(gè)簡(jiǎn)單的例子:
class my
{
public:
const int& get() const; // #5
int& get(); // #6
private:
int m_n;
};
int my::get() const
{
return m_n;
}
int& my::get()
{
return m_n;
}
我們看到在my這個(gè)類(lèi)中,有兩個(gè)幾乎相同的函數(shù),為什么這樣的函數(shù)也可以重載呢?它們居然有用了相同的參數(shù)列表,不過(guò)此時(shí)的參數(shù)列表是空的。
不用害怕,有后綴const存在,可保無(wú)虞!
那么我們就來(lái)看看,這個(gè)const到底干了些什么勾當(dāng)。
對(duì)于普通的成員函數(shù)來(lái)說(shuō),C++編譯器在調(diào)用它們的時(shí)候,都會(huì)隱式的提供一個(gè)this指針,所以,其實(shí)我們剛剛看到的那兩個(gè)函數(shù)的參數(shù)列表不是空的,只不過(guò)編譯器在欺騙我們,當(dāng)然,我們可不會(huì)上它的當(dāng)。那么現(xiàn)在,我們?nèi)绱死斫馑鼈儯?/font>
const int& get(my* this) const; // #7
int& get(my* this); // #8
這依然使我們產(chǎn)生了一些視覺(jué)上的不快,雖然,它們不再使空參數(shù)列表,但是參數(shù)列表好像還是相同,顯然,如果真是這樣,真兩個(gè)函數(shù)肯定是無(wú)法重載的,那么問(wèn)題一定就在哪個(gè)const后綴上。
那么現(xiàn)在,我就可以回答大家的疑問(wèn):在成員函數(shù)的后綴加上const之后,將會(huì)導(dǎo)致這個(gè)函數(shù)的參數(shù)列表輕微的改變,被影響的參數(shù)就是那個(gè)鬼鬼祟祟的this指針,this指針將會(huì)被const重新修飾。從而那兩個(gè)函數(shù),我們就可以寫(xiě)成這樣:
const int& get(const my* this); // #9
int& get(my* this); // #10
OK
小功告成,現(xiàn)在,立即重載!
好,那么,如何去區(qū)分這兩個(gè)函數(shù)不同的調(diào)用呢?
其實(shí),只要理解了以上的思想,這已經(jīng)不存在障礙了,只要我們能夠讓一個(gè)對(duì)象成為const類(lèi)型,那么它就會(huì)自動(dòng)去選擇被后綴const修飾過(guò)的重載函數(shù)。
我們?cè)谇懊嫣岬竭^(guò)const可以修飾函數(shù)的返回值?這是怎么回事呢?對(duì)一個(gè)返回值進(jìn)行修飾?有意義嗎?
當(dāng)然,當(dāng)然。其實(shí),這不是一個(gè)語(yǔ)法上的問(wèn)題,而是一個(gè)邏輯上的問(wèn)題。我們還是使用那個(gè)萬(wàn)人迷例子吧:
class my_int
{
public:
my_int(int n)
{
m_n = n;
}
my_int& operator+(my_int a);
private:
int m_n;
}
my_int& operator+(my_int a)
{
m_n += a.m_n;
return *this;
}
現(xiàn)在,我們返回的是一個(gè)my_int對(duì)象的引用,如果,我們不限定它是一個(gè)const類(lèi)型的話(huà),將會(huì)允許下面的這種怪物出現(xiàn):
my_int a(3), b(5), c(19);
(a += b) = c;
顯然,這是不應(yīng)該被允許的一種表達(dá)式,對(duì)一個(gè)結(jié)果進(jìn)行賦值,是一種非常愚蠢和丑陋的行為,所以,我們要這樣修改我們的operator+函數(shù):
const my_int& operator+(my_int a);
OK,一切大功告成,打瞌睡和發(fā)呆是我的愛(ài)好?。?/font>