條款03:盡可能使用 const
const允許你指定乙個語義約束,也就是指定乙個「不該被改動」的物件。
const如果出現在星號左邊,表示被指物是常量,如果出現在星號右邊,表示指標自身是常量:如果出現在星號兩邊,表示被指物和指標都是常量。
如果被指物是常量,有些程式會將關鍵字const寫在型別之前,有些人會把它寫在型別之後,星號之前。兩種寫法意義相同:
void f1(const widget* pw) void f2(widget const* pw) //f2獲得乙個指標指向乙個常量widget物件f1也是
對於迭代器也是一樣:
std::vectorvec const std::vector::iterator iter = vec.begin(); *iter = 10 ; //沒問題,改變的是iter所指之物 ++iter ; //錯誤,const不可被改變 std::vectorconst_iterator citer = vec.begin(); *citer = 10; //錯誤,const 不可被改變 ++citer; //ok
const威力最大的地方是面對函式的應用,在乙個函式宣告內,const可以和函式返回值,各引數,函式自身,產生關聯。
返回乙個const會增加程式的安全性和高效性。
class rational ; const rational operator* (const rational& lhs, const rational& rhs);
上面的函式要求返回乙個const物件,可以使如下**無法通過編譯:
rational a,b,c; if(a * b = c)
也許只是單純的書寫錯誤,不易察覺,但是可以用const檢測出來。
至於const引數,和local const 一樣,你應該在必要使用的時候使用它們,除非你有需要改動引數或者local物件,否則請將它宣告為const.
const 成員函式
將const實施於成員函式的目的,是為了確認該成員函式可作用於const物件身上。它們使得class介面比較容易理解。並且使操作const物件成為可能。改善c++程式效率的乙個根本辦法是以pass by reference-to-const方式傳遞物件。而此技術的前提是我們有const成員函式可以用來處理取得的const物件。
class textblock //operator for const object char& operator //operator for non-const object private: std::string text; };
textblock 的operator可被這麼使用:
textblock tb("hello"); std::cout << tb[0]; //呼叫non-const textblock::operator const textblock ctb("world"); std::cout << ctb[0];
或者void print(const textblock& ctb)
所以:std::cout << tb[0]; //ok tb[0] = 'x'; //ok std::cout 《錯誤起因於企圖對乙個「由const 版之operator返回」的const char& 施行賦值操作。
也請注意,non-const operator的返回型別是個reference to char ,不是char,如果operator只是返回乙個char,下面的句子就無法通過編譯;
tb[0] = 'c';
因為如果函式的返回型別是個內建型別,那麼改動函式返回值從來就是不合法的。(仔細想想,我從來沒遇到過修改返回值的情況。。。)。
bitwise const:成員函式只有在不更改任何成員變數(static 除外)的時候,才能說是const.正是c++對常量的定義。但是:
class ctextblock private: char* ptext; };
這個class 不適當的將operator宣告為const函式,而該函式返回乙個reference指向物件內部值。operator實現**並不更改ptext,於是編譯器可以通過,並認為它是bitwise。但是:
const ctextblock cctb("hello"); char* pc = &cctb[0]; //呼叫const operator取得乙個指標,指向cctb的資料 *pc = 'j'; //cctb現在是jello
因為更改的是指向的資料而不是指標本身,所以是可以通過編譯的。
這種情況匯出了logical constness:可以修改const成員函式內的某一些bits,但只有在客戶端偵測不出的情況下才如此:
class ctextblock ; std::size_t ctextblock::length() const return textlength; }
使用 mutable釋放掉non-static成員變數的bitwise constness約束:
mutable std::size textlenghth; mutable lengthisvalid;
在cosnt 和non-const成員函式中避免重複
將某些東西宣告為const可幫助編譯器偵測出錯誤用法,const可被施加於任何作用域內的物件,函式引數,函式返回型別,成員函式。
編譯器強制實施bitwise constness,但你編寫程式時應該使用「概念上的常量性」
當const和non-const 成員函式有著實質等價的實現時,令non-const版本呼叫const版本可避免**重複(但可能出現。。。兩次型別轉換)
Item 3 盡量使用 const
char greeting hello char p greeting non const data,non const pointer const char p greeting non const pointer,const data char const p greeting const po...
Effective C 盡量使用const
char greeting hello char p greeting const char p greeting char const p greeting const char const p greeting const在 號左邊,代表指標指向的物件是const的。如果在右邊,代表這個指標是c...
條款3 盡可能使用const
對於const關鍵字,剛學習程式設計確實會搞的一頭霧水。單看這乙個關鍵字感覺還可以理解,那如果再加上static和define呢?const關鍵字在我們實際落地寫 或者看別人的 時對我們大有裨益,不僅可以幫助我們減少 的風險,對以後別人維護 好處也很大。單挑出乙個條款來講它,應該知道其在程式設計中的...