C++的const類成員函數(解釋爲什麼非const成員函數不能訪問const對象的數據成員)

1. 在C++中只有被聲明爲const的成員函數才能被一個const類對象調用。

如果要聲明一個const類型的類成員函數,只需要在成員函數列表後加上關鍵字const, 例如:
class Screen {
    public:
        char get() const;
};
在類體之外定義const成員函數時,還必須加上const關鍵字,例如:
char Screen :: get() const {
    return _screen[_cursor];
} 
若將成員函數聲明爲const,則不允許通過其修改類的數據成員。
值得注意的是,如果類中存在指針類型的數據成員即便是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];    // 不好的風格,但不是錯誤的
}
m_sName 不能通過setName()函數修改,但是 setName函數可以修改其所指向的字符。

2. const成員函數可以被對應的具有相同形參列表的非const成員函數重載,例如:

class Screen {
public:
char get(int x,int y);
char get(int x,int y) const;
};
在這種情況下,類對象的常量性決定調用哪一個函數:
  • const成員函數可以訪問非const對象的非const數據成員,const數據成員,也可以訪問const對象內的所有數據成員;
  • 非const成員函數只可以訪問非const對象的任意的數據成員(不能訪問const對象的任意數據成員);
    上述原因可詳見C++Primer(5th)231頁, 在默認情況下,this的類型是指向類類型非常量版本的常量指針,例如 Screen類中,this類型爲 Screen *cosnt。當在成員函數的後面加上const關鍵字時,隱式的將this指針修改爲 const Screen *const 即指向類類型常量版本的常量指針。根據初始化原則,我們不能將一個常量指針賦值給一個非常量指針
  • 作爲一種良好的編程風格,在聲明一個成員函數時,若該成員函數並不對數據成員進行修改, 應儘可能將該成員函數聲明爲const成員函數。
發佈了31 篇原創文章 · 獲贊 17 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章