Effective C++ 條款03

儘可能使用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。

 

參考:https://blog.csdn.net/unirrrrr/article/details/80890252

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章