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

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

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

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

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

//Test.h
template <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()函数的地址。所以出现无法解析外部符号的错误.
我们模板代码的实现体在一个文件里,而实例化模板的测试代码在另一个文件里,编译器编译一个文件时并不知道另一个文件的存在,因此,模板代码就没有进行实例化,编译器自然不会为其生成代码,因此会抛出一个链接错误!

猜你喜欢

转载自blog.csdn.net/prefect_boy/article/details/76895224