成員函數如果是const意味著什麼?
有兩個流行概念:物理常量性和邏輯常量性。
C++對常量性的定義采用的是物理常量性概念,即const 成員函數不可以更改對象內任何non-static成員變量。例如:
1 class CTextBlock 2 { 3 public: 4 ...... 5 std::size_t length() const; 6 7 private: 8 char* pText; 9 std::size_t textLength; 10 bool lengthIsValid; 11 }; 12 13 std::size_t CTextBlock::length() const 14 { 15 if (!lengthIsValid) 16 { 17 textLength = std::strlen(pText);// 發生錯誤,在const成員內不能賦值給textLength和lengthIsValid 18 lengthIsValid = true; 19 } 20 return textLength; 21 }
上面代碼中發生錯誤,在const成員內不能賦值給textLength和lengthIsValid,怎樣解決呢?
解決方法很簡單:利用C++的一個與const相關的擺動場:mutable。
mutable釋放掉non-static成員變量的物理常量性約束:
1 class CTextBlock 2 { 3 public: 4 ...... 5 std::size_t length() const; 6 7 private: 8 char* pText; 9 mutable std::size_t textLength;//這些成員變量可能總是會被改變,即使是在const成員函數內 10 mutable bool lengthIsValid; 11 }; 12 13 std::size_t CTextBlock::length() const 14 { 15 if (!lengthIsValid) 16 { 17 textLength = std::strlen(pText);//現在可以這樣了 18 lengthIsValid = true; 19 } 20 return textLength; 21 }
不能修改值的意思是不能修改類數據成員的值
一般一個成員函數不修改數據成員的話都會加個const
即使不加,某些編譯器也會提示你加一個
通過指針也能實現。在C++中,由const修飾的成員函數的函數體內部,是不能夠對成員變量進行修改的。這個特性被用來保證某些成員函數在實現過程中,避免由於程序員大意而對數據進行了錯誤的修改;同時也說明此成員函數是非修改性的。如只需要返回成員變量的成員函數就被聲明為const類型(const的位置在函數定義參數列表之後)推廣開來,在const成員函數中也不能夠調用非const的成員函數。這是因為非const成員函數可能會改變成員變量的值,這與const成員函數的定義相違背。但是在某些情況下,需要在const函數中改變成員變量。這就需要把成員變量設置成mutable類型。如class C{public:void func(const int& p) const{i = p;}private:mutable int i;};如果變量i不聲明為mutable類型,則編譯不會通過。如果成員變量是一個類類型或者結構類型,而在const函數中調用這些變量的成員函數,除了用mutable聲明外,還可以用一種變通的方法:class D{public:void op(){}}class C{public:void func(const int& p, D& d) const{i = p;d.op();}private:mutable int i;D cd;};然後在調用時,參數D& d以*this作為輸入,也可以達到調用非const函數的作用。P.S 最近閱讀相關的文章,又學到了一種方法,能夠使得在const成員函數中調用非const成員函數。就是使用const_cast<運算符。它能夠使得const去掉const的屬性,使得violate屬性去掉violate屬性。上面的例子就可以寫成。