1. 程式人生 > >C++11新特性(83)-enum前置宣告

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

 


覺得本文有幫助?請分享給更多人。

閱讀更多更新文章,請掃描下面二維碼,關注微信公眾號【面向物件思考】