【c++】模板为什么不支持分离编译

来源:互联网 发布:vb.net app.path 编辑:程序博客网 时间:2024/05/16 09:19

我们在写代码的时候,通常情况下我们定义.h文件.cpp。我们把函数的声明放在.h文件中,函数定义放在.cpp中。
什么是分离编译
分离编译模式是指:一个程序(项目)由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将所有目标文件连接起来形成单一的可执行文件的过程。

//Test.hvoid fun();//函数声明//Test.cpp#include"Test,h"void fun()//函数实现/定义{    ...}//test.cint main(){    fun();//函数调用}

分离编译的优点
1,有错误时可以快速找到
2,实现模块多用

下来我么你看看模板的分离编译会怎么样!

//Test.htemplate <class T>class AA{public:    AA();private:    int _a;};//Test.cpp#include"Test.h"template<class T>AA<T>::AA()    :_a(0)    {}main.cpp//主函数#include"Test.h"int main(){    AA<int> a1;    return 0;}

当我们运行程序时:
这里写图片描述
我们看到出了一个链接错误
注意:链接错误通常是找不到函数的实现体
首先我们先了解下编译器对我们代码总共做了哪些事!
这里写图片描述
分析:
编译器在“预编译阶段”会将#include包含的文件拷贝进当前main.cpp文件中,那么经过预编译阶段后main文件中便会包含模板的声明,在“编译阶段”main文件中的AA a1相当于告诉编译器要将模板类实例化为AA类型,但是当模板分离编译时,此时main文件中只会实例化出fun()函数的声明,而Test.cpp中fun()函数的定义并不会实例化,所以当在“链接阶段”符号表的重定位时并不会找到fun()函数的地址。所以出现无法解析外部符号的错误.
我们模板代码的实现体在一个文件里,而实例化模板的测试代码在另一个文件里,编译器编译一个文件时并不知道另一个文件的存在,因此,模板代码就没有进行实例化,编译器自然不会为其生成代码,因此会抛出一个链接错误!

原创粉丝点击