標籤:detail 需要 details 調用 https tool get ret 封裝
http://blog.csdn.net/lihao21/article/details/8634876
我們知道,在C++中,若一個變數聲明為const類型,則試圖修改該變數的值的操作都被視編譯錯誤。例如,
[cpp] view plain copy
- const char blank = ‘’;
- blank = ‘\n’; // 錯誤
物件導向程式設計中,為了體現封裝性,通常不允許直接修改類對象的資料成員。若要修改類對象,應調用公有成員函數來完成。為了保證const對象的常量性,編譯器須區分不安全與安全的成員函數(即區分試圖修改類對象與不修改類對象的函數)。例如,
[cpp] view plain copy
- const Screen blankScreen;
- blankScreen.display(); // 對象的讀操作
- blankScreen.set(‘*’); // 錯誤:const類對象不允許修改
在C++中,只有被聲明為const的成員函數才能被一個const類對象調用。
要聲明一個const類型的類成員函數,只需要在成員函數參數列表後加上關鍵字const,例如,
[cpp] view plain copy
- class Screen {
- public:
- char get() const;
- };
在類體之外定義const成員函數時,還必須加上const關鍵字,例如
[cpp] view plain copy
- char Screen::get() const {
- return _screen[_cursor];
- }
若將成員成員函式宣告為const,則該函數不允許修改類的資料成員。例如,
[cpp] view plain copy
- class Screen {
- public:
- int ok() const {return _cursor; }
- int error(intival) const { _cursor = ival; }
- };
在上面成員函數的定義中,ok()的定義是合法的,error()的定義則非法。
值得注意的是,把一個成員函式宣告為const可以保證這個成員函數不修改資料成員,但是,如果據成員是指標,則const成員函數並不能保證不修改指標指向的對象,編譯器不會把這種修改檢測為錯誤。例如,
[cpp] view plain copy
- 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_Name不能被修改,但m_sName是char *類型,const成員函數可以修改其所指向的字元。
const成員函數可以被具有相同參數列表的非const成員函數重載,例如,
[cpp] view plain copy
- class Screen {
- public:
- char get(int x,int y);
- char get(int x,int y) const;
- };
在這種情況下,類對象的常量性決定調用哪個函數。
[cpp] view plain copy
- const Screen cs;
- Screen cc2;
- char ch = cs.get(0, 0); // 調用const成員函數
- ch = cs2.get(0, 0); // 調用非const成員函數
小結:
1)const成員函數可以訪問非const對象的非const資料成員、const資料成員,也可以訪問const對象內的所有資料成員;
2)非const成員函數可以訪問非const對象的非const資料成員、const資料成員,但不可以訪問const對象的任意資料成員;
3)作為一種良好的編程風格,在聲明一個成員函數時,若該成員函數並不對資料成員進行修改操作,應儘可能將該成員函式宣告為const 成員函數。
C++的const類成員函數