讀書筆記《Effective c++》 條款03 儘可能使用const
阿新 • • 發佈:2019-02-13
const是一種約束,告訴編譯器和其他程式設計師,這個值不要被修改。
a.函式返回值是常量: 例如有理數的乘法過載:
const Rational operator* (const Rational& lhs, const Rational& rhs);
這樣寫可以避免一些暴行,例如 Rational a, b, c;
(a * b) = c;
b.const成員函式
將const實施於成員函式的目的,是為了確認改成員函式可作用於const物件身上。
兩個成員函式如果只是常量性不同,可以被過載。例如:
using std::cout; using std::endl; using std::string; class TextBlock { public: const char& operator[](std::size_t position) const { cout << "const版本" << endl; return text[position]; } char& operator[](std::size_t position) { cout << "普通版本" << endl; return text[position]; } TextBlock(const string& s) :text{ s } { } private: std::string text; }; void print(const TextBlock& tb) { cout << tb[0] << endl; } int main() { TextBlock tb{ "Hello" }; cout << tb[0] << endl; // 普通版本 const TextBlock ctb{"World"}; cout << ctb[0] << endl; // const普通版本 print(TextBlock{ "OhGod" }); // const普通版本 }
此小節也引出了mutable關鍵字。
c.在const和non-const成員函式中避免重複
上面的類中,constt版本和non-const版本在實際的程式碼中可能會有大量相同的程式碼,所以如果像過載一樣,能讓non-const版本呼叫const版本,
將會減少很多重複程式碼:
先將*this轉換成const物件,然後就可以呼叫const版本的[],最後將返回值去const。char& operator[](std::size_t position) { return const_cast<char&>(static_cast<const TextBlock&>(*this)[position]); //cout << "普通版本" << endl; //return text[position]; }
但是如果反過來,用const版本呼叫non-const是肯定不行的,因為const承諾不改變物件的邏輯狀態。
總結
a.將某些東西宣告為const可以幫助編譯器偵測出錯誤語法。const可被施加於任何作用於內的物件、函式引數、函式返回型別、成員函式本體。
b.編譯器強制實施bitwise constness,但你編寫程式時應該使用“概念上的常量性”(conceptual constness)。
c.當const和non-const成員函式有著實質等價的實現時,令non-const版本呼叫const版本可避免程式碼重複。