[問題] 專案中的 include/lib 資料夾該放什麼

作者: poolongkong (普攏貢)   2020-07-12 20:42:57
其實小弟想發問的問題有兩個,
首先是如標題說明的,在一個專案裡的 include & lib 資料夾分別代表什麼意思,
我知道跟 header file、static library、shared library 有關,
但我想問的不是在 source code include header file 或是 compile time 的 linker
相關問題,
而是說 "什麼概念的 source code" 該放在 include & lib 資料夾。
第二個問題是 class 的 declaration & definition 到底怎麼寫才是對的,
因為不管是學校或是網路上的入門教學,都會建議介面跟實作要分開,
幾乎所有的例子都是 declaration 放在 .h 檔、definition 放在 .cpp 檔,
所以原本小弟一直以為 class 的 declaration (.h) 就是放在 include、class 的
definition (.cpp) 就是放在 lib,
但看了一些 open source 的專案才發現不是我想的這樣。
以最近在看的 LLVM 的 SmallVector 當例子,
(簡單說明一下,SmallVactor 是對 elements 較少的情況而去優化的 vector)
在 LLVM 的 source code 中可以分別找到
SmallVector.h
https://code.woboq.org/llvm/llvm/include/llvm/ADT/SmallVector.h.html
以及
SmallVector.cpp
https://code.woboq.org/llvm/llvm/lib/Support/SmallVector.cpp.html
但翻一下 code 可以發現幾乎 95% 的功能實作都是在 .h 檔裡面,
並且也沒有所謂的介面與實作分開。
雖然寫了一段時間的程式,但對這一塊真的沒什麼研究,
google 也是找到一堆 header file 與 library 之間的差異,
但我想問的不是 link 之類的問題啊~~
最後再簡述一下問題:
1. 專案中的 include & lib 資料夾中的 source code 應該放什麼概念的 code
才是對的?
2. (X) 介面與實作分開這件事是有必要的嗎?
(O) 介面與實作分開這件事該怎麼分割比較適合?
先謝謝看完問題的各位~
作者: nh60211as   2020-07-12 21:50:00
那個實作在.h應該是因為template不能實作在.cpp不然會link time error,其他不清楚請別人回答了
作者: Lipraxde (Lipraxde)   2020-07-12 23:14:00
比較細節的放 lib,其他的放 include,畢竟寫在 header裡真的太方便了(x
作者: Dracarys (MayShowGunMore)   2020-07-12 23:22:00
除了template的原因,我猜大概是為了方便inline
作者: loveme00835 (髮箍)   2020-07-13 03:27:00
你覺得介面實作分開是為了什麼?把東西放在標頭檔再分離編譯的情況, 對不同的 translation unit 來說, 引入的多份型別/模板/物件彼此其實是不一樣的; 但因為要保證 ODR 所以它們被視為是相同的實體. 即使模板也可以細分有無特化/具現化, 一般最簡單的使用通常都是無特化再透過 implicit instantiation 來自動產生實作, 因為要完整的程式碼才有辦法做的這件事, 所以才會有模板實作都要寫在標頭檔的錯覺.事實上模板也可以寫成像你說的一樣: 介面/實作分離,但要很明白你的目的, 因為這種寫法很容易違反 ODR.先明白 include 只是複製貼上, 那再來從 ODR 的角度思考為什麼有的東西可以放在標頭檔裡其他的卻會造成連結錯誤, 再來想想這樣分開寫到底有什麼好處. 如果今天我分開寫沒辦法得到上述的好處, 也不會造成連結錯誤的話, 當然全寫在標頭檔裡比較方便囉 (節省同步的成本).開發軟體最經常遇到的就是改變, 最害怕的也是改變.開發上分成兩個角色: library user & developer. user 因為只是不需要知道細節, 所以有一份標頭檔和已經編好的函式庫檔就可以做開發, developer 有任何改動,如果不是改在標頭檔內, 所以 user 所需要做的最多就是重新連結而已. 介面/實作分離一方面就是要避免 user 重複做編譯的動作 (編譯防火牆), 如果函式庫含有商業機密通常也會這樣做 (看授權) 所以撰碼的時候身分需要持續切換, 作為 developer 時就要思考怎樣讓 user 減少編譯次數, 在介面上做最少改動; 作為 user 的時候思考介面設計是否方便合理.簡單說如果一個實作萬年不變, 而且沒有需要/可能減少編譯次數/時間的考量, 就會直接寫在標頭檔裡.以 ISO 標準教學流程 [P1389R1] 來說這個應該歸在最後的工具介紹階段裡, 對語言特性更了解後才比較清楚該怎麼拿捏. 只是為了教學方便很容易跳過這些基礎知識, 不過關鍵字: ODR 可以先深入學習.
作者: ofd168 (大色狼來襲)   2020-07-21 09:30:00
每次看love大的推文都能學到很多

Links booklink

Contact Us: admin [ a t ] ucptt.com