[问题] 专案中的 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