盡可能使用 const

2021-06-27 21:36:14 字數 2838 閱讀 5295

使用 const 的好處在於它允許指定一種語意上的約束——某種物件不能被修改——編譯器具體來實施這種約束。通過 const,你可以通知編譯器和其他程式設計師某個值要保持不變。只要是這種情況,你就要明確地使用 const  ,因為這樣做就可以借助編譯器的幫助確保這種約束不被破壞。

對指標來說,可以指定指標本身為 const,也可以指定指標所指的資料為const,或二者同時指定為 const,還有,兩者都不指定為 const:

char *p = "hello"; //  非 const 指標,

// 非 const 資料

const char *p = "hello"; // 非 const 指標,

//const 資料

char * const p = "hello"; // const 指標,

// 非 const 資料

const char * const p = "hello"; // const 指標,

//const 資料

語法並非看起來那麼變化多端。一般來說,

const 的一些強大的功能基於它在函式宣告中的應用。在乙個函式宣告中,const 可以指的是函式的返回值,或某個引數;對於成員函式,還可以指的是整個函式。

讓函式返回乙個常量值經常可以在不降低安全性和效率的情況下減少使用者出錯的機率。實際上正如條款 29 所說明的,對返回值使用 const 有可能提高乙個函式的安全性和效率,否則還會出問題。

例如,看這個在條款 19 中介紹的有理數的 operator*函式的宣告:

const rational operator*(const rational& lhs,const rational& rhs);

很多程式設計師第一眼看到它會納悶:為什麼 operator*的返回結果是乙個 const 物件?因為如果不是這樣,使用者就可以做下面這樣的壞事:

rational a, b, c;

(a * b) = c; //  對 a*b 的結果賦值     

關於 const 引數沒什麼特別之處要強調——它們的運作和區域性 const 物件一樣。但,見條款 m19,const 引數會導致乙個臨時物件的產生。

如果成員函式為 const,那就是另一回事了。

const 成員函式的目的當然是為了指明哪個成員函式可以在 const 物件上被呼叫。但很多人忽視了這樣乙個事實:僅在 const 方面有不同的成員函式可以過載。這是 c++的乙個重要特性。

const函式說明:類的成員函式後面加 const,表明這個函式不會對這個類物件的資料成員(準確地說是非靜態資料成員)

作任何改變。

在設計類的時候,乙個原則就是對於不改變資料成員的成員函式都要在後面加 const,而對於改變資料成員的成員函式不能加 const。所以const 關鍵字對成員函式的行為作了更加明確的限定:有 const 修飾的成員函式(指 const 放在函式引數表的後面,而不是在函式前面或者參數列內),只能讀取資料成員,不能改變資料成員;沒有 const 修飾的成員函式,對資料成員則是可讀可寫的。

除此之外,在類的成員函式後面加 const 還有什麼好處呢?那就是常量(即 const)物件可以呼叫 const 成員函式,而不能呼叫非const修飾的函式。正如非const型別的資料可以給const型別的變數賦值一樣,反之則不成立。

class string 

// 用於 const 物件的 operator

const char& operator(int position) const

private:

char *data;

};string s1 = "hello";

cout << s1[0]; // 呼叫非 const

// string::operator

const string s2 = "world";

cout << s2[0]; // 呼叫 const

// string::operator

通過過載 operator 並給不同版本不同的返回值, 就可以對 const 和非 const string 進行不同的處理:

string s = "hello"; //  非 const string 物件

cout << s[0]; // 正確——讀乙個

// 非 const string

s[0] = 'x'; // 正確——寫乙個

// 非 const string

const string cs = "world"; // const string 物件

cout << cs[0]; // 正確——讀乙個

// const string

cs[0] = 'x'; // 錯誤!—— 寫乙個

// const string

還要注意,非 const operator的返回型別必須是乙個 char 的引用——char本身則不行。如果 operator 真的返回了乙個簡單的char,如下所示的語句就不會通過編譯:

s[0] = 'x';

解釋:s[0]返回乙個固定的型別,只會返回乙個臨時變數,對臨時變數的修改絕對是非法的,沒有意義。

因為,修改乙個「返回值為固定型別」的函式的返回值絕對是不合法的。即使合法,由於 c++「 通過值(而不是引用)來返回物件」 (見條款 22)的內部機制的原因,s.data[0] 的乙個拷貝會被修改,而不是 s.data[0] 自己,這就不是你所想要的結果了。

條款23所述:必須返回乙個物件時,不要試圖嘗試用引用,那個物件的含義是在函式中新開闢的物件,物件存在於堆,棧中,存在析構,及記憶體洩露等各種問題。

但此處,卻必須要返回乙個引用,而不能返回值,因為,此處不屬於返回乙個物件那個範疇,可以返回類的資料成員的引用。

盡可能使用const

const定義語義約束 制定乙個不被改動的物件,編譯器會強制實施這項約束。只要某值保持不變時事實,就應該確實說出來,這樣編譯器可以確保這項約束不違反。const多才多藝 可以用在classes外部修飾global或namespace作用域中的常量,或修飾檔案 函式 或區塊作用於中被宣告為static...

盡可能使用const

一 中心思想 1 將某些東西宣告為const可幫助編譯器偵測出錯誤用法。const可被施加於任何作用域內的物件 函式引數 函式返回型別 函式返回型別 成員函式本體 2 編譯器強制實施bitwise constness,但你編寫程式時應該使用 概念上的常量性 3 當const和non const成員函...

盡可能使用const

編譯器可以對其進行靜態資料型別檢查 若你在編寫函式時,並沒有打算改變引數,這是就應該將引數的型別設定為const reference,這樣既可以保證引數的常量性,又提高了傳值的效率 若函式的返回值時const pointer,則返回值不可被直接修改,而且返回值必須賦值給const同種型別 令函式返回...