Effective C++ 条款03:尽可能使用const
生活随笔
收集整理的這篇文章主要介紹了
Effective C++ 条款03:尽可能使用const
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
場景一 用于修飾指針
char greeting[] = "Hello"; char* p = greeting; // non-const pointer, non-const data const char* p = greeting; // non-const pointer, const data char* const p = greeting; // const pointer, non-const data const char* const = greeting; // const pointer, const dataconst在*左邊,表示被指物是常量,指針所指向的內容不能修改,但是可以修改指針,讓指針指向其他對象。
const在*右邊,表示指針自身是常量,指針不能修改,不能指向其他對象,但是當前指向的內容可以修改。
const在*的兩側,表示指針自身是常量,被指物也是常量,指針不能指向其他對象,當前指向的內容也不能改變。
場景二 用于對象前、后
void f1(const Widget* pw); void f2(Widget const * pw);兩種表達式的效果是一樣的,都在*的左邊,說明被指物是常量。
場景三 用于對STL迭代器的修飾
std::vector<int> vec; const std::vector<int>::iterator iter = vec.begin(); // iter的作用相當于 T* const *iter = 10; // 沒問題,改變iter所指物 iter++; // 錯誤,iter是const std::vector<int>::const_iterator cIter = vec.begin(); // cIter的作用相當于 const T* *cIter = 10; // 錯誤,*cIter是個const ++cIter; // 沒問題,改變cIter場景四 用于返回值
class Rational {...}; const Rational operator* (const Rational& lhs, const Rational& rhs); Rational a, b, c; ... (a * b) = c; // 顯然在把返回結果設置為const以后,就不允許這樣的操作發生 if (a * b = c) // 如果設置返回值為const的時候,這種手誤的操作也不會發生場景五 用于成員函數本體
const成員函數
class TextBlock { public:'''const char& operator[](std::size_t position) const // operator[] for const對象{return text[position];}char& operator[](std::size_t position){return text[position];]} private:std::string text; } // 調用一 TextBlock tb("Hello"); std::cout << tb[0]; // 調用non-const TextBlock::operator[] const TextBlock ctb("World"); std::cout << ctb[0]; // 調用const TextBlock::operator[] // 調用二 void print(const TextBlock& ctb) {std::cout << ctb[0]; // 調用const TextBlock::operator[]... } // 調用三 std::cout << tb[0]; //沒問題,讀一個non-const TextBlock tb[0] = 'x'; //沒問題,寫一個non-const TextBlock std::cout << ctb[0]; //沒問題, 讀一個const TextBlock ctb[0] = 'x'; //錯誤,寫一個const TextBlock, 錯誤的原因在于operator[]的返回值為const注意以上兩個函數的返回值都為&,如果返回值是一個char的話,tb[0]= ‘x’;是無法通過編譯的;
那是因為,如果函數的返回類型是個內置類型,那么改動函數返回值從來就不合法。縱使合法,C++以by value返回對象這個事實意味被改動的其實是tb.text[0]的一個副本,不是tb.text[0]自身,那不會是你想要的行為。
場景六 bitwise constness和logical constness
class CTextBlock { public:...char& operator[](std::size_t position) const //bitwise const 聲明,但其實不適當 private:char* pText; } // 調用 const CTextBlock cctb("Hello"); // 聲明一個常量對象 char* pc = &cctb[0]; // 調用const operator[]取得一個指針,指向cctb的數據 *pc = 'J'; // cctb現在有了"Jello"這樣的內容 // 說明 // const 修飾函數體,說明函數體內不能修改任何non-static成員變量,在函數題內卻是沒有修改成員變量,但是最后還是修改成功了,那是因為返回值不是char;bitwise constness的主張是成員變量一個bit都不能修改,以上情況導出所謂的logical constness。 class CTextBlock { public:...std::size_t length() const; private:char* pText;std::size_t textLength; //最近一次計算的文本區塊長度bool lengthIsValid; //目前的長度是否有效 }; // 成員函數實現 std::size_t length() const {if (!lengthIsValid) {textLength = std::strlen(pText); //錯誤,在const成員函數內不能賦值給textLength和lengthIsValidlengthValid = true;}return textLength; }場景七 mutable用法
// 用mutable(可變的)釋放掉non-static成員變量的bitwise constness約束 class CTextBlock { public:...std::size_t length() const; private:char* pText;mutable std::size_t textLength; //這些成員變量可能總是被更改,即使在const成員函數內。mutable bool lengthIsValid; }; std::size_t CTextBlock::length() const {if (!lengthIsValid) {textLength = std::strlen(pText);lengthIsValid = true;}return textLength; }場景八 const實現non-const成員函數
在const和non-const成員函數中避免重復
class TextBlock { public:...const char& operator[](std::size_t position) const {... // 邊界檢查... // 日志記錄數據 ... // 檢驗數據完整性return text[position];}char& operator[](std::size_t position) {... // 邊界檢查... // 日志記錄數據... // 檢驗數據完整性return text[position];} private:std::string text; }; // 可以看到以上有非常嚴重的代碼重復, 改進就是用const operator[] 實現 non-const operator[] class TextBlock { public:...const char& operator[](std::size_t position) const {.........return text[position];}char& operator[](std::size_t position) {return const_cast<char&>(static_cast<const TextBlock&>(*this)[position]);// const_cast轉型是因為返回類型,static_cast轉型是為了轉成const對象。} };總結
轉載于:https://www.cnblogs.com/zhonghuasong/p/7290712.html
總結
以上是生活随笔為你收集整理的Effective C++ 条款03:尽可能使用const的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梦到钓了一条鱼是什么意思
- 下一篇: 表达式求值(二叉树方法/C++语言描述)