《模板的分离编译问题》

一般情况下,在建立工程时我们喜欢将函数的声明与定义放在不同的文件中(.h/.cpp),这样当我们在编写源文件程序时需要用到其他文件中的函数时只需在本文件中包含进该函数声明所在的头文件便可引用该函数,这种方式也是标准库函数的使用方式,使编程编程效率大大提高,减少了可复用性代码的重复编写,深得人们喜爱,但当学习了C++中模板之后,以类似的方式组织文件时却出现了问题,这究竟又是怎么一回事呢?接下来,我们就一起来探索探索。

编译+链接:

这里写图片描述

分离编译:
我们将fun()函数的定义放在MoBan.cpp中,将fun()函数的声明放在MoBan.h中进行编译,结果如下:

这里写图片描述

分析:
编译器在“预编译阶段”会将#include包含的文件拷贝进当前Test.cpp文件中,那么经过预编译阶段后Test文件中便会包含模板的声明,在“编译阶段”Test文件中的Test<int> t相当于告诉编译器要将模板类实例化为Test<int>类型,但是当模板分离编译时,此时Test文件中只会实例化出fun()函数的声明,而MoBan.cppfun()函数的定义并不会实例化,所以当在“链接阶段”符号表的重定位时并不会找到fun()函数的地址。所以出现无法解析外部符号的错误。如下图:

这里写图片描述

声明/定义放在一块编译:
我们将fun()函数的声明与定义均放在MoBan.hpp中进行编译,结果如下:

这里写图片描述

分析:
当我们将模板的声明与定义放在同一个MoBan.hpp文件中时,在“预编译阶段”便会将模板的定义也包含进Test文件中,于是乎在“编译阶段”Test文件便会实例化出函数的定义,进而在“链接阶段”便会找到函数的地址。


其实,还有一种可以解决模板分离编译的方法,那就是在模板声明的MoBan.h中进行显式实例化,通过定义template class Test<int>达到对模板显式实例化的作用。但我们不推荐使用此种方式:1、实例化依赖于调用者。2、旧的编译器可能不支持。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值