標籤

C++ (12) Linux (6) MacOSX (4) Makefile (3) Matlab (3) Ubuntu (3) Android (2) C (1) Refactoring (1)

2012年4月23日 星期一

[C++] const 篇


在之前的文章中有提到
我們如果要為類別(class)撰寫介面函式如get的話
可以寫成:

vector& getNameList() {
   return _nameList;
}


const vector& getNameList() const {
   return _nameList;
}

不過其實const的學問是很博大精深的

像const, *, 之類的關鍵字
通通只能作用位在它左邊的敘述

不過const實在是太常用了
所以像上面const vector&這種const左邊空空的情況
也是被允許的(不然對初學者來說就太痛苦了)
而這種左邊空空的const會被預設只作用於右手邊那一個

比較好的寫法應該是
vector const& getNameList() const {
   return _nameList;
}

這樣就更能表達出const是用來修飾左邊vector
也就是嘗試修改回傳的vector所裝的東西是不被允許的
程式出現這樣的用法會直接被編譯器(compiler)擋掉
出現discard qualifer的字樣
而它指的qualifer就是const

那問題回到為什麼要把const擺到vector的右手邊而不是待在左邊就好?
原因在於有時候我們想要取得的
不是reference而是pointer
就不能只是把const擺在左邊當個形容詞就好了

舉例說明:

string* & getNameList(){
   return _nameList;
}

const string* & getNameList() const {
   return _nameList;
}

第二個有加const的涵式根本過不了compiler
完全一樣的寫法為什麼把vector換成另一個資料型態string*就不行?

原因在於const string*&這句會被compiler解讀成
「_nameList所帶有的值是不得被更改」
也就是說const只作用在string身上而已
根本沒有作用到string*這整串

但光這個解釋並不足以說明為什麼compiler會一直該
重點是在那個const string*後面的reference &

這相當於你既要函式是constant method(不得更改其資料成員data member)
又想把資料型態是string*的資料成員_nameList
以非const的reference傳出去
這樣你到底是想改還是不想改?

解決方法就是
「你得把你想保護的東西放在const的左手邊」
如下所示:

string* const& getNameList() const {
   return _nameList;
}

如此一來const才有辦法保護到資料型態是string*的_nameList

不懂得可以留言問我或是再參考這篇

沒有留言:

張貼留言