讀Defective C++隨筆 3

來源:互聯網
上載者:User
讀Defective C++隨筆 3


不盡知用兵之害者,則不能盡知用兵之利也 ——《孫子兵法》

5.const完備問題
對C來說,const看起來是很合理的,將參數聲明成const的,可以利用編譯器的語法檢查避免一些不期望的修改錯誤,而且可能協助編譯器做一些最佳化。多數官方文獻都強烈要求程式員編寫const完備的C++代碼,極力避免const_cast,但現實中大部分代碼只能是基本使用了const。問題在於,一但涉及到類,const就會引出很多的問題。

有C++經驗的人應該都體會過,任何使用了const的代碼都將迫使任何接觸它的代碼支援const,同時任何不使用const的代碼都迫使任何接觸它的代碼不使用const。所以我們對如下代碼習以為常:
const Foo& GetFoo() const;
Foo& GetFoo();

這對類方法函數被稱作const重載。為了同一類型在const和非const時都能用,我們不得不把很多方法寫兩遍,而且必須是完全重寫,因為它們中任何一個都不能調用另外一個,除非你使用被說成邪惡的const_cast,還有傳說中更邪惡的C風格強制轉換。然後Foo的方法也必須支援const重載,以此類推。

不過簡單的屬性訪問函數一般都不長,但如果不是簡單的訪問呢?比如如果需要緩衝最近訪問的資料以提高效率,這時必須修改一些內部成員,但它又必須可以在const對象調用。於是C++裡有了mutable關鍵字,用來指定一些成員可以被const方法修改。

另外,對於函數參數,同樣的問題也存在,而且有時非常不可思議。比如vector<Foo*>類型的變數不能傳給const vector<const Foo*>&類型的參數,當然,const vector<Foo*>&和vector<const Foo*>&類型的參數更不能。那應該怎麼做?如果你想到了,那恭喜你,你C++及格了。原則上正確的做法是傳遞iterator而不是集合對象的引用。所以才有T::const_iterator和T::iterator兩個類。等等,為什麼需要兩個類而不是一個iterator類加const關鍵字?因為iterator需要做自加或自減,加const關鍵字就改不了了,所以只能再寫一遍。那下一個問題,如果不是傳參數,而是要把vector<Foo*>的變數賦給const vector<const Foo*>&的變數怎麼辦?歡迎作答。

很明顯,必須把同樣的事情做兩遍有違“重用”的目標,但C++選擇了安全性。如果我們使用了const_cast,那是我們程式員的責任,是因為我們沒有做出完美的設計。

const在C++裡的另一個副作用是,加const的類型和不加const的類型是不同的類型,所以vector<Foo*>和vector<const Foo*>是不同的類型,所以編譯器產生兩份完全一樣的代碼。所以,我們都知道用了STL編譯出的程式就會很大。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.