C++11新特性(83)-enum前置宣告
大型開發都會遇到的問題
隨著軟體規模的擴大,包含在一個工程中的模組的數量在不斷增長,模組之間的依賴關係也日益複雜。這裡只舉一個相對簡單的例子:一個包含2個類,5個檔案的工程。
ImportantClass.h
標頭檔案中聲明瞭建構函式,doWork成員函式和資料成員buffer。
ImportantClass.cpp
cpp檔案中為建構函式和doWork提供了最簡單的實現。
userclass.h
聲明瞭建構函式,解構函式和doSomething成員函式以及ImportClass型別的資料成員。由於ip是ImportClass的例項,所以構建UserClass的宣告中需要ImportantClass標頭檔案(包含類結構資訊)。
userclass.cpp
userclass.cpp為建構函式,解構函式和doSomething成員函式提供了最簡單的實現。
main.cpp
程式碼中建立了一個UserClass物件並呼叫了它的doSomething成員函式。
為了理解上述程式碼中的問題,首先明確一件事:一般來講C++編譯器編譯的編譯物件是工程中的那些cpp檔案。.h檔案一邊不會單獨編譯,而是和包含它的cpp檔案一起編譯。具體到例子工程,可以大致如下理解:
importclass.cpp在編譯時同時編譯了importclass.h檔案。
userclass.cpp在編譯時同時編譯的userclass.h檔案和importclass.h檔案。
main.cpp在編譯時同時編譯了userclass.h和importclass.h檔案。
上面程式碼中的主要問題是main.cpp真正希望使用的是UserClass,但由於userclass.h又引用了importantclass.h,所以產生了額外的依賴關係。
除了main.cpp以外,importclass.cpp和userclass.cpp中實際會使用到ImportClass類,這兩處依賴關係是必要的。
前置宣告
上述問題的解決方法就是前置宣告,具體程式碼如下。
代 碼中的變化有兩點,一個是資料ImportantClass成員的型別變成了指標型別;另一個是include語句變成了class宣告語句。兩個變化缺 一不可,第二個變化是第一個變化的前提條件。因為這裡只是聲明瞭指標型別,所以只要告訴編譯器ImportantClass一個類就夠了。真正的型別資訊 在userclass.cpp中提供。這種方式就是前置宣告。以下是修改過的userclass.cpp檔案:
通過這種方式消除了main.cpp對於ImportantClass的依賴。專案的依賴層次越多,前置宣告的效果也就越明顯。
enum前置宣告
C++11中,enum型別也可以前置聲明瞭。下面直接引用C++ Primer中的例子。
enum intValues : unsigned long long; //不限定作用域的,必須指明型別
enum class open_modes; //限定作用域的也可以指定,如果不指定則預設int
實際的列舉值可以在另外的cpp檔案中另外定義。
作者一句話
細節決定成敗,儘可能的提高效率應該是每個程式設計師的追求;為程式設計師提供精雕細刻的手段也應該是一個強大語言的追求。
程式碼下載地址
https://github.com/xueweiguo/OOThinking/tree/master/20180603%20ForwardDeclarationOfEnum/ForwardDeclarationOfEnum
覺得本文有幫助?請分享給更多人。
閱讀更多更新文章,請掃描下面二維碼,關注微信公眾號【面向物件思考】