概念了解
分离式编译
一个项目由若干个源文件共同实现,而每个源文件(.cpp)单独编译成目标文件(.obj),最后将所有目标文件连接起来形成单一的可执行文件(.exe)的过程。
编译过程
预处理–》编译–》汇编–》链接
- 预处理阶段
头文件展开、条件编译指令、宏替换 - 编译阶段
将第一步产生的文件同其他文件一起编译成汇编代码 - 汇编阶段
将汇编源码转换成可重定位目标文件 - 链接阶段
进行符号解析和重定位,将可重定位目标文件链接成可执行目标文件
模板
C++Primer中的定义:
模板是C++中泛型编程的基础。一个模板就是一个创建类或函数的蓝图或者说公式。
当使用一个vector这样的泛型类型,或者find这样的泛型函数时,我们提供足够的信息,将蓝图转换为特定的类或函数(实例化)。
这种转换发生在编译时。
我们可以捕捉到一个信息,使用的时候 对模板进行实例化,且发生在编译过程的编译阶段。
编译单元
在预处理阶段会进行头文件展开,通俗的理解就是.h+.cpp文件就是一个编译单元。
为什么模板不支持分离式编译
在编译阶段,每一个cpp文件都是相对独立的,并不知道另一个编译文件的存在,若存在外部调用,会在链接阶段进行重定位。
模板的实例化其实只能发生在本编译单元的调用。如果出现非本编译单元的模板调用,也就是分离式编译,只能等待链接时重定位,但是模板并没有实例化,所以会出现链接出错。
代码实例
模板函数声明在test.h中,定义在test.cpp中,调用在main.cpp中(链接出错)
![[外链图片转存失败(img-kgFa3FKq-1566462362822)(./1.png)]](https://i-blog.csdnimg.cn/blog_migrate/8312b8f18a30d9d78bb115022e695471.png)
![[外链图片转存失败(img-trFpMcC1-1566462362823)(./2.png)]](https://i-blog.csdnimg.cn/blog_migrate/e3e8b7bccc45ad972c9bff0c917ba269.png)
模板函数声明在test.h中,定义在main.cpp中,调用在main.cpp中(运行成功)
![[外链图片转存失败(img-jiIazI4O-1566462362823)(./3.png)]](https://i-blog.csdnimg.cn/blog_migrate/bf7d0604aeb9ece4993bef11a18e4a5f.png)
![[外链图片转存失败(img-aVGzVKIt-1566462362823)(./4.png)]](https://i-blog.csdnimg.cn/blog_migrate/ad8c136fea965d58bced7386db8e03bc.png)
模板函数声明在test.h中,定义在test.h中,调用在main.cpp中(运行成功,因为头文件会在预处理阶段对头文件展开)
![[外链图片转存失败(img-eqKoMDGu-1566462362824)(./5.png)]](https://i-blog.csdnimg.cn/blog_migrate/66044c0015c5dc9703ae1965e29c0b7b.png)
总结
这个简单的链接出错问题,其实原因涉及到了很多方面,经过分析,其实能够加深对编译过程的理解。
本文深入探讨了C++中的分离式编译过程,包括预处理、编译、汇编和链接阶段,以及模板在这一过程中的作用和限制。特别强调了模板不支持分离式编译的原因,并通过代码实例说明如何正确使用模板。
468

被折叠的 条评论
为什么被折叠?



