C++霧中風景5:Explicit's better tha
關於Explicit還是Implicit一直是程式語言中能讓程式設計師們幹起架的爭議。那些聰明的老鳥總是覺得Implicit的規則讓他們能夠一目十行,減少樣板程式碼的羈絆。而很多時候,Implicit的很多規則會讓新手或者是合作開發的搭檔痛苦不堪。文章的標題也寫明瞭筆者的態度,顯式的在程式碼之中指明自己的意圖,會讓程式更加明晰。所以也借今天這篇文章,我們來聊聊Explicit關鍵字。
1.隱式類型別轉換
好吧,先看一段程式碼:
(為了簡單起見,我這裡就沒有過載
class A {public: A(int s) {}; };void printA(A a) { cout上面這段程式碼是可以透過編譯執行的,可能有些小夥伴會比較困惑,為蝦米這裡printA函式明明需要接受的是一個A型別,但是傳入的一個int型別仍然能夠編譯透過。
這就被稱之為隱式類型別轉換,它存在於自定義的類建構函式中。C++的編譯器會對只有一個引數的建構函式也定義了一個隱式轉換,將該建構函式對應資料型別的資料轉換為該類物件。也就是說,上段程式碼其實可以翻譯成下面的程式碼:
class A {public: A(int s) {}; };void printA(A a) { cout這裡10作為int型別的引數,透過隱式的類型別轉換,被預設構造了一個A型別的匿名物件,傳入了函式printA,所以程式碼能夠正常的編譯執行。顯然,這種型別的程式碼是十分Confused。所以我們來看看這麼解決這個問題的。
有一個折衷的解決方案,將程式碼做下面的修改:
void printA(A &a) { cout這裡透過引用型別就可以避開這個陷阱,因為編譯器不會構造這個匿名物件的引用,所以此時的程式碼是無法透過編譯的。
顯然,這個方案改變了我們不使用引用型別的初衷,我們看看C++有木有更加優雅的解決方案。
2.Explicit關鍵字
explicit主要用於"修飾"建構函式,使得它不用於程式中需要透過此建構函式進行"隱式"轉換的情況。指定此關鍵字,需要隱式轉換方可進行的程式將不能編譯透過。
class A {public: explicit A(int s) {}; };void printA(A a) { cout這裡我們新增了explicit關鍵字,阻止了編譯器的隱式類型別轉換,讓程式碼更加明晰了。當然,我們這裡是可以使用static_cast關鍵字可以顯式的型別轉換,透過程式碼的編譯。
int main() { printA(static_castexplicit關鍵字只對一個引數的建構函式有效,需要多個實參的建構函式不能用於隱式型別轉換。
3.討論一下
Scala
型別系統幾乎是Scala之中最複雜的內容,Scala設計的討巧之處,是透過implicit關鍵字,顯式的指定了隱式類型別轉換。雖然隱式類型別轉換減少了很多冗餘的程式碼,但是這樣的設計會降低程式碼的可讀性。Scala也一直因為可讀性被詬病,所以這樣的設計,見仁見智。Golang
如果是介面interface與Python是類似的鴨子型別,不需要什麼隱式轉換了。
而如果是struct類的話,那Golang就十分嚴格的執行強型別的判斷。不符合是不行的。Java
Java一直是拒絕這種Confuse做法的語言,所以透過一大堆繁瑣的樣板程式碼規避這樣的問題。
“Explicit's better than implicit”。Explicit保證了程式碼的可讀性和維護性。這點對於一個系統的工程性是很有幫助的。Implicit的轉換容易帶來那種“看上去很美,但是非常容易出錯”的 feature 。希望我們能夠告別對它的依賴。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2618/viewspace-2814545/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- C++霧中風景18:C++20, 從concept開始C++
- C++霧中風景番外篇:理解C++的複雜宣告與宣告解析C++
- C++霧中風景12:聊聊C++中的Mutex,以及拯救生產力的BoostC++Mutex
- C++霧中風景10:聊聊左值,純右值與將亡值C++
- C++霧中風景15:聊聊讓人抓狂的Name ManglingC++
- C++霧中風景17:模板的非推斷語境與std::type_identityC++IDE
- C++霧中風景16:std::make_index_sequence, 來試一試新的黑魔法吧C++Index
- C++關鍵字explicitC++
- C++ explicit&noexcept關鍵字C++
- 迷霧大陸 S4 47
- 2008 5 5: I want to get know you better
- [大霧霧霧霧] 告別該死的 EFCore Fluent APIAPI
- [大霧霧霧霧] 告別該死的 EFCore Fluent API (續)API
- Better And Better for Mac - Mac手勢神器BABMac
- C++ 建構函式 explicit 關鍵字 成員初始化列表C++函式
- Better than better,白山EC2.0釋出
- Better data, better finance-方以涵NaN
- C# explicit與implicitC#
- 資料解讀採暖季:冬季霧霾元凶:燒煤、沒風
- Ship Better Code
- 滴滴大資料在汽車金融風控場景中的應用大資料
- C#中的explicit和implicit瞭解一下吧C#
- 軟體研發中也有5S 管理?
- Explicit (Manual) Data Locking (364)
- [C++]C風格、C++風格和C++11特性的執行緒池C++執行緒
- c++:-5C++
- 騎上腳踏車,在風景如畫的遊戲世界中穿梭旅行遊戲
- [C++][程式設計風格]C++命名規則C++程式設計
- Service異常:Service Intent must be explicitIntent
- Android:Unable to find explicit activity classAndroid
- 暴風魔鏡4s rio怎麼樣 暴風魔鏡4s rio評測
- Google C++ 程式設計風格指南:其他 C++ 特性GoC++程式設計
- Google C++程式設計風格指南(三):C++ 類GoC++程式設計
- 小米5s值得買嗎 小米5s評測
- Writing Better AdaptersAPT
- Why MVC is Better?(翻譯)MVC
- Why Java is better than .NETJava
- Object C學習筆記5-ARC forbids explicit message* 編譯錯誤Object筆記ORB編譯