儘可能使用const
1.const和指針
如果const關鍵字在星號左邊,表示被指物是常量; const T* t
如果出現在星號右邊,表示指針自身是常量; T* const t
如果出現在星號兩邊,表示被指物和指針兩者都是常量;const T* const t
總結:const靠近*號,那麼申明的指針就是常量。遠離*的const就是描述指針的所指量爲常量
2.const和迭代器
STL中的迭代器實際上本質是以指針實現的,所以可以把一個迭代器看作是一個指針,可以用指針的性質去套迭代器的性質。
std::vector <int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
const std::vector <int>:: iterator it = vec.begin();
std::vector <int> ::const_iterator iit =vec.begin();
*it =10;
// ++it; 錯誤
// *iit = 30; 錯誤
iit++;
這裏的it就是常量,*it是可以被改變的;*iit是常量,iit可以被改變。
總結:const_iterator 相當於const T* (指向的內存不能被改變)
const ……iterator 相當於T* const
3.另函數返回一個常量,可以降低因用戶錯誤造成的意外
例如重載*操作符時的聲明如下:
const Complex operator* (const Complex& lhs, const Complex& rhs);
返回const對象可以避免像 (a*b)= c 這樣的情況發生,通常表現爲這樣的錯誤:
if (a*b = c)//實際是想判斷是否相等,即應爲==而不是=
此時因爲a*b返回的對象是const對象,不可修改,因此會報錯,使得程序員發現這個錯誤並修改。
4.通過mutable去除non-static成員變量的bitwise constness約束:
bitwise const認爲,成員函數只有在不更改對象的任何成員變量時纔可以說是const,也就是它不更改對象內的任何一個bit。
bitwise const正是c++對常量性的定義,因此const成員函數不能更改對象內任何non-static成員變量。
class Text {
public:
std::size_t length() const;
private:
char* pText;
std::size_t textLength;
bool lengthValid;
};
std::size_t Text::length() const {
if (!lengthValid) { //錯誤,在const函數內要改變textLength和lengthValid的值
textLength = std::strlen(pText);
lengthValid = true;
}
return textLength;
}
這樣的code是不能通過bitwsie const的編譯器,編譯器提示:
cannot assign non-static data member within const funciton ……
如果要使textLength、lengthValid
可以修改,需要用mutable
釋放掉non-static成員變量的bitwise const約束:
...
private:
mutable std::size_t textLength; ///mutable的意思就是成員變量可能總是被更改,即使在const成員函數內
mutable bool lengthValid;
...
加上mutable ,編譯器報警消失
5. 在const和non-const成員函數中避免重複
一句話就是:利用const函數實現內容,去實現non-const函數,就是需要進行數據類型的轉換
const char& operator[] (std::size_t position) const {
... ////函數實現
return text[position];
}
char& operator[] (std::size_t position) {
return const_cast<char&>(static_cast<const Text&>(*this)[posistion]);
}
這裏的下面一個操作符,裏面有兩次轉型,第一次用來爲*this從其原始類型TextBlock& 轉型爲const TextBlock&,通過添加const
第二次是從const operator[ ] 的返回值中移除const。