Guru of the Week 條款19:自動轉換 (轉)
GotW #19 Automatic Conversions:namespace prefix = o ns = "urn:schemas--com::office" />
著者:Herb Sutter
翻譯:K ][ N G of @rk™
[宣告]:本文內容取自網站上的Guru of the Week欄目,其著作權歸原著者本人所有。譯者kingofark在未經原著者本人同意的情況下翻譯本文。本翻譯內容僅供自學和參考用,請所有閱讀過本文的人不要擅自轉載、傳播本翻譯內容;本翻譯內容的人請在閱讀瀏覽後,立即刪除其。譯者kingofark對違反上述兩條原則的人不負任何責任。特此宣告。
Revision 1.0
Guru of the Week 條款19:自動轉換
難度:4 / 10
(從一種型別到另一種型別的自動轉換有時是極度方便的。本期GotW透過一個典型的例子說明為什麼自動轉換同時也是極度危險的。)
[問題]
標準的string不具有向const char*進行自動轉換的能力。它應該有嗎?
* * * * *
[背景]:把string作為C風格的const char*來進行訪問,經常是很有用的。實際上,string也確有一個成員c_str()專門用來完成這個任務——該函式返回const char*。下面的程式碼體現出兩者的區別:
string s1("hello"), s2("world");
strcmp( s1, s2 ); // #1 (錯誤)
strcmp( s1.c_str(), s2.c_str() ) // #2 (ok)
如果能做到#1就再好不過了,但#1卻是錯誤的,因為strcmp需要的是兩個指標,而string和const char*之間卻不存在自動轉換。#2是正確的,但卻因為要顯式的c_str()而使程式碼變長。如果我們能使用#1難道不是更好一些嗎?
[解答]
標準的string不具有向const char*進行自動轉換的能力。它應該有嗎?
不,理所不該。避免編寫自動轉換幾乎總是一個可取的辦法,不管是以轉換運算子編寫還是以single-argument non-explicit constructor(單引數非顯式建構函式)編寫。[注1]
說隱式轉換一般是不的,有兩個主要原因:
a) 它會影響過載解析(overload resolution);並且
b) 它會使“錯誤的”程式碼被不聲不響的編譯透過。
如果存在一個從string到const char*的自動轉換,那麼這個轉換動作將會在任何認為需要的地方被呼叫。這便意味著,你會遇到各種各樣的轉換問題——與你在採用non-explicit轉換建構函式時所遇到的問題是一樣的。你將會很容易的寫出看上去正確而實際上不正確的程式碼,這些程式碼原則上應該導致失敗,但卻可能由於古靈精怪的巧合而被編譯透過並完成了與預期完全不同的操作。
有很多這樣的例子。下面就是一個簡單的例子:
string s1, s2, s3;
s1 = s2 - s3; // 歐噢,或許原本是想要"+"
其中的減法毫無意義,應該是錯誤的。然而,如果存在從string到const char*的隱式轉換,那麼這段程式碼就會被編譯透過,因為編譯器會不聲不響的將兩個string轉換為const char*,然後對兩個指標施以相減操作。
摘自GotW編碼標準,作為小結:
——避免編寫轉換運算子(Meyers96: 24-31; Murray93: 38, 41-43; Lakos96: 646-650)
[注1]:這裡我所關注的是隱式轉換的普遍問題;其實關於「為什麼string class不應該具有向const char*的轉換」這個問題,還有其它一些原因。這兒有幾個進一步討論該內容的參考:
Koenig97: 290-292
Stroustrup94 (D&E): 83
[部分參考]
Koenig97 Andrew Koenig.
"Ruminations on C++"
Addison-Wesley, 1997
Lakos96 John Lakos.
"Large-Scale C++ Software Design"
Addison-Wesley, 1996
Meyers96 tt Meyers.
"More Effective C++"
Addison-Wesley, 1996
Murray93 Robert Murray.
"C++ Strategies and Tactics"
Addison-Wesley, 1993
Stroustrup94 Bjarne Stroustrup.
(or D&E) "The Design and Evolution of C++"
Addison-Wesley, 1994
(完)
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-993866/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Guru of the week:#19 自動型別轉換. (轉)型別
- Guru of the Week 條款27:轉呼叫函式 (轉)函式
- Guru of the Week 條款28:“Fast Pimpl”技術 (轉)AST
- Guru of the Week 條款09:記憶體管理(上篇) (轉)記憶體
- Guru of the Week 條款10:記憶體管理(下篇) (轉)記憶體
- Guru of the Week 條款24:編譯級防火牆 (轉)編譯防火牆
- Guru of the Week 條款30附錄:介面原則 (轉)
- Guru of the Week 條款05:覆寫虛擬函式 (轉)函式
- Guru of the Week 條款13:物件導向程式設計 (轉)物件程式設計
- Guru of the Week 條款07:編譯期的依賴性 (轉)編譯
- Guru of the Week 條款11:物件等同(Object Identity)問題 (轉)物件ObjectIDE
- Guru of the Week 條款14:類之間的關係(上篇) (轉)
- Guru of the Week 條款15:類之間的關係(下篇) (轉)
- Guru of the Week 條款16:具有最大可複用性的通用Containers (轉)AI
- C++ articles:Guru of the Week #1 (轉)C++
- Guru of the week:#18 迭代指標. (轉)指標
- Guru of the Week 條款08:GotW挑戰篇——異常處理的安全性 (轉)Go
- Guru of the Week 條款23:物件的生存期(第二部分) (轉)物件
- Guru of the Week 條款22:物件的生存期(第一部分) (轉)物件
- Guru of the Week 條款21:程式碼的複雜性(第二部分) (轉)
- Guru of the week:#17 型別對映. (轉)型別
- Guru of the Week 條款20:程式碼的複雜性(第一部分) (轉)
- C++ articles:Guru of the Week #4 -- Class Mechantics (轉)C++
- Guru of The week #20 程式碼的複雜性 Ⅰ. (轉)
- C++ articles:Guru of the Week #3:使用標準庫 (轉)C++
- Guru of the Week #5:虛擬函式的重新定義 (轉)函式
- More Effective C++ 條款19 (轉)C++
- GitHub 第一坑:換行符自動轉換Github
- Java資料型別自動轉換(++ ,+=)Java資料型別
- 將RichTextBox設定為自動換行或非自動換行 (轉)
- C++ Gotchas 條款62:替換Global New和Global Delete (轉)C++Godelete
- 【轉】css樣式自動換行(強制換行)CSS
- PostgreSQL自定義自動型別轉換(CAST)SQL型別AST
- spring mvc3.1.0 日期自動轉換SpringMVC
- php之資料型別自動轉換PHP資料型別
- 一款開發小程式自動wxss轉換的命令列工具命令列
- More Effective C++ 條款4 (轉)C++
- More Effective C++ 條款6 (轉)C++