类模版的分离编译

一、.普通函数不需要分离编译而模版函数需要分离编译

1、对于普通函数:vodi Fun()

在Fun.h文件中声明如下:

void Fun();
在Fun.cpp中定义如下:

#include"Fun.h"

void Fun()
{
	cout << "Fun()" << endl;
}
测试用例如下:

#include"Fun.h"


void TestFun()
{
Fun();
}

这个时候并不会产生什么错误,运行结果如下:


2、对于模版函数void TemplateFun(const T&x)

在TemplateFun.h文件中声明如下:

template<class T>
void TemplateFun(const T&x);
在TemplateFun.cpp中定义如下:

#include"TemplateFun.h"

template<class T>
void TemplateFun(const T&x)
{
	cout << "TemplateFun()" << endl;
}
测试用例如下:

#include"TemplateFun.h"

void TestTemplateFun()
{
	TemplateFun(1);
}
这个时候程序会报一个链接错误,只是拿到了函数的声明,而拿不到函数的定义

二、程序的编译与执行的四个阶段

以下同过一张图来直观的描述出来:



三、链接错误产生的原因

c++在调用外部函数的,在编译是其实只是用一条jmp跳转指令代替这个调用代码,例如jmp 0xABCDEFG,这个地址可能是任意的,然而关键是这个地址上有一行指令来进行真正的call f动作,也就是说,跳转的地址是一条真正的调用指令call

但是call的地址是一个任意的无效地址,因为在编译阶段,本单元是不知道其他单元函数的地址的,于是这个无效的地址的修正是放在链接阶段,链接器根据调用函数单元的符号表,修改该无效地址。

这样问题就来了。因为模版仅在需要的时候才会具体实例化出来。在编写的模版.h文件中没有具体的定义,仅仅只有其声明,因此编译次单元的时候不会生成相应的函数二进制代码,这就导致了在链接阶段会在其他调用模版 单元函数的是报错,编译器给出一个链接错误

四。解决办法

1、方法一:

在模板头文件 xxx.h 里面显示实例化->模板类的定义后面添加 template class SeqList<int >; 一般不推荐这种方法,一方面老编译器可能不支持,另一方面实例化依赖调用者。(不推荐)

2、方法二:

将声明和定义放到一个文件 "xxx.hpp" 里面,推荐使用这种方法。

五。模版的优缺点

1、优点:

(1)模板复用了代码,节省资源,更快的迭代开发,C++的标准模板库(STL)因此而产生。
(2)增强了代码的灵活性。

2、缺点:

(1)模板让代码变得凌乱复杂,不易维护,编译代码时间变长。
(2)出现模板编译错误时,错误信息非常凌乱,不易定位错误。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值