C++ 常物件和常函式

奇妙之二進位制發表於2020-12-01

常函式

在成員函式的宣告及定義的形參括號後邊加上const關鍵字,注意如果存在宣告的話,宣告和定義都必須加上const,這就叫常函式,常函式指的是常成員函式,沒有普通函式不能用const修飾。

class Person {
public:
	void test() const;
};

void Person::test() const {
}

在設計類的時候,一個原則就是對於不改變資料成員的成員函式都要在後面加 const,而對於改變資料成員的成員函式不能加 const。所以 const 關鍵字對成員函式的行為作了更加明確的限定:

(1)有 const 修飾的成員函式(指 const 放在函式參數列的後面,而不是在函式前面或者參數列內),只能讀取資料成員,不能改變資料成員;沒有 const 修飾的成員函式,對資料成員則是可讀可寫的。
(2)除此之外,在類的成員函式後面加 const 還有什麼好處呢?那就是常量(即 const)物件可以呼叫 const 成員函式,而不能呼叫非const修飾的函式。

記住這幾條規則就夠用了:

  • const物件只能呼叫const成員函式
  • const成員函式只能呼叫const成員函式
  • const成員函式中不能改變成員變數的值
  • 存在宣告的話,宣告和定義都必須加上const

常函式機制探索

const本質上修飾的是this指標,網上很多這樣寫:
void print() const => const 類名 * const this,
實際上this指標本身就是const指標,即其值不可修改,也就是指向不可修改,並非const功勞,所以應該寫成:
void print() const => const 類名 * this,
所以const函式保證了this指向的物件是個常物件,導致我們無法修該物件的值。

值得注意的是,如果類中存在指標型別的資料成員即便是const函式只能保證不修改該指標的值,並不能保證不修改指標指向的物件。如:

class Name {
public:
void setName(const string &s) const;
private:
    char *m_sName;
};
void setName(const string &s) const {
    m_sName = s.c_str();      // 錯誤!不能修改m_sName;
for (int i = 0; i < s.size(); ++i) 
    m_sName[i] = s[i];    // 不好的風格,但不是錯誤的
}

常物件

const關鍵字能夠修飾物件,得到只讀物件,只讀物件只能呼叫const成員函式。

相關文章