重新認識標頭檔(C/C++ Header Files)
讓我們來複習一下標頭檔的用途:對小型程式而言,基本上我們只需要把所有的原始檔一起編譯,就可以產生出所要的執行檔。但是如果到了大型的專案呢?很多程式勢必是朝向模組化並且講究可再使用性高的方向去設計。其中最關鍵的就是可再使用性(Reusability),但別人要怎重複使用這段程式呢?
首先,回想一下我們如果完全不使用標頭檔又要把一個程式切成好幾個原始檔完成,勢必得在各個原始檔前面加上必要的「事先宣告(Forware Declaration)」,這些東西對我們來說是相依性高的,因為這些事先宣告可能跟原始碼本身的實作沒有關係。所以為了可再使用性,我們把這些事先宣告都放進了標頭檔,如此一來,不論是動態函式庫或是靜態鏈結,我們都可以透過引用這個標頭檔而再用該函式庫。
但是也不是每種語言都有標頭檔的設計,例如 Java,就透過 package 的命名機制(有興趣可以詳讀這篇文章),避免歧義,讓編譯器可以直接找到所需要的 Symbol。
標頭檔的概念很容易理解,要照著做也只是把變數拉出去而已。那麼到底還有什麼值得寫出一篇文章的地方呢?
不要把標頭檔當垃圾桶
有些人可能會為了方便,把所有的東西一股腦兒往標頭檔塞。來假設最極端的例子,全部塞到 common.h 一個標頭檔。Makefile 的設計是這樣:一旦標頭檔的內容被更改了,那麼所有跟此標頭檔相依的檔案都會被重新編譯。所以在這個例子中,即使你只是在 common.h 中加了一行註解,也會導致整個程式都得重新編譯。
儘量降低各個標頭檔的相依性
再次強調:Reusability。為了降低相依性,有多少個標頭檔、什麼東西要放在標頭檔,自然也是個學問。目前比較常見的用法,是一個原始檔搭配一個標頭檔。
除此之外:
- 不要把非公開的函數(例如一些 helper functions)宣告或是變數也拉到標頭檔去。
- 全域變數的宣告儘量的少,儘可能使用 static 變數。
- 不要把函數主體放在標頭檔,除非是 inline function(非公開使用依舊除外)
標頭檔內含有靜態陣列宣告可能會使程式肥大
如果您覺得這篇文章有幫助,邀請您分享讓更多人受益,一起成就更好的自己。您可以免費訂閱我的文章,以便第一時間獲取最新內容。謝謝您的閱讀和支持!