By Ryui Liu 2011/11/26
C++中const關鍵字允許你指定一個語義限制即指定這是一個“不能被改動”的對象,而編譯器會強制實施這項限制。當你确實不希望某值保持不變時,你就該确實的說出來,這樣編譯器就可以幫助你確定這個值不被改變。
const可以在class外部修飾global或namespace作用域中的常量,可以修飾檔案、函數、或區塊作用域中被static聲明的對象,可以修飾classes内部的static或non-static成員變量,也可以修飾常量指針、指針常量、指向常量的指針常量;const最有威力的用法還是在函數聲明時,可以和函數的傳回值,各個參數,函數自身産生關聯。
const修飾變量時,如果const關鍵字出現在星号的左邊,表示被指物是常量(沒有星号時(即非指針變量)也适用),如果出現在星号的右邊,則表示指針自身是常量,如果在星号兩邊都出現,則被指物和指針兩者都是常量。
const int i = 10;
char greeting [] = "hello world";
char greeting2[] = "qu world";
const char *p = greeting;
char const *q = greeting; // p和q都是常量指針
char * const cq = greeeting; // cq為指針常量,不能改變它的指向
*p = "aaaa";// error
P = greeting2; //ok
cq = greeting2; // error
*cq ="aaaaa"; //ok
const char* const pq = greeting; //pq是指向常量的指針常量
STL跌代器iterator 是普通指針,如果在其前面加上const修飾時,則該指針不能被改變,既疊代器不能改變,而const_iterator是一個指向常量的指針。例如:
std::vector<int > vec;
const std::vector<int>::iterator iter = vec.begin();
*vec = 10 ;//ok
++vec; // error
std::vector<int>::const_iterator cIter = vec.begin();
*vec = 10;//error
++vec; //ok
const修飾函數時,可以給參數加上const不希望修改參數的值,也可以給傳回值加上const不希望無意中改變傳回值。例如:
class aa{.....};
const aa operator*(const aa& a1,const aa& a2);
此處則不希望改變operator *的傳回值,假如一個混混沌沌的程式員寫出if(a*b = c), 編譯器給他錯誤提示了;如果沒有加上const,或許他會抓狂的。
在c++面向對象程式設計中,常用const來修飾類的成員函數,這樣做是為了确認該成員函數可以作用于const對象身上。這樣做有兩個重要理由:第一、它們使class接口比較容易了解,得知哪個函數可以改動對象内容而哪個函數不可以,例如常見的get/set函數;第二、它們使“操作const對象”成為可能,這對編寫高效代碼是個關鍵。
需要提示的是:兩個成員函數如果隻有常量性不同即一個有const修飾,另一個沒有,可以被重載。
const char& operator[](std::size_t position)const {return ...}; //operator [] for const對象
char &operator[] (std::size_t position)(return ...);//operator[] for non-const 對象。
衆所周知,我們在const成員函數中不能修改成員變量,但當需要修改時就需要另外一個關鍵字---mutable.
例如
class MutableTest
{
public:
MutableTest();
~MutableTest();
void Output() const;
int GetOutputTimes() const;
private:
mutable int m_iTimes;
};
MutableTest::MutableTest()
{
m_iTimes = 0;
}
MutableTest::~MutableTest()
{}
void MutableTest::Output() const
{
cout << "Output for test!" << endl;
m_iTimes++;
}
int MutableTest::GetOutputTimes() const
{
return m_iTimes;
}
在這個例子中,将Output函數修飾為const,卻希望記錄輸出的次數,這時就需要改變m_iTimes的值,這個時候就需要mutable關鍵字來突破const關鍵字的限制了:m_iTimes在常成員函數中也可以被改變。
總結:const可以被施加于任何作用域内的對象、函數參數、函數傳回類型、成員函數本體,将某些東西聲明為const可以幫助編譯器偵測錯誤用法。當需要在const的成員函數内部修改成員變量時,可以求助于mutable關鍵字。