C++ 为什么编写模板类时要把方法的实现写在头文件中,而不能像写普通类一样写在源文件中?

1、回答标题的问题

这里说下我自己的理解,如有不正确请各位大佬斧正。想要解决这个问题需要先了解C++代码的编译过程。

C++将代码编译生成可执行文件的过程可以分为三步:预编译 → 编译 → 链接。预编译时,会展开头文件,将包含的头文件的代码整个复制到当前文件中来。编译过程是生成二进制机器指令的过程。C++采用分离式编译,即,在编译时,对预编译源文件生成的文件(obj文件)进行单独编译,和其他文件没有任何关系。这时就有一个问题,当编译一个文件时,遇到了函数func,当前文件中只有预编译时拉进来的func的声明,而没有定义,无法生成func的二进制机器指令。这个问题,链接阶段会专门解决。在编译阶段,这些函数会暂时被标记为 “未解析的外部符号”。当进入链接阶段时, 链接器会专门为所有的未解析符号在其他文件中寻找对应的二进制机器指令,整个工程都链接好,就能正常执行了。

以上说的都是普通C++代码的编译过程。但是模板并不普通。模板只有在真正被使用到的时候才实例化,才生成二进制机器指令。当模板类的定义和实现分别写在了头文件和源文件中,而且main.cpp中还包含了模板类的头文件。那么编译main.cpp的obj文件时,势必会遇到模板类成员方法的声明,但是这里没有定义,先标记为未解析的外部符号。到了链接时,根据未解析的外部符号去到模板类源文件的obj文件中寻找其实现,找不到,因为他还没有被实例化,链接失败。此时,如果模板类成员方法的实现也在头文件中,那么就可以解决问题。

2、如何实现定义和实现分开写也能编译

非要把定义和实现分开写在头文件和源文件的话也不是不行。需要在源文件中添加模板类的实例化。

这个方法还是有局限性,因为你不知道类的使用方会套用什么类型,你需要对每个类型在cpp文件中挨个实例化一次,这就很麻烦,尤其是使用方套用的类型是自己定义了一个类的话,还是会出现链接错误。

写这篇文章参考了很多其他文章,下面一一列出。
C++程序是如何编译的?

C++ 编译,运行过程 详解。

C++类模板是如何编译的?

C++中模板类的编译过程
C++模板编译

C++模板为什么定义和实现必须都写在头文件?

模板为什么必须定义在头文件
关于C++为什么模板类中的模板函数只能写在头文件

C++模板类如何实现头文件和源文件分离?

C++模板类/函数,将头文件与源文件分离

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值