模板

一 :概念:模板是泛型编程的基础,所谓泛型编程就是编写与类型无关的逻辑代码,是一种复用的方式,模板分为模板函数和模板类

二:模板函数

1:模板函数格式:

 

2:模板函数的实例化

<1>.隐式实例化------》推演为实例化一个步骤,推演形参类型

<2>显示实例化

三:模板类

1:模板类格式:

2:模板的模板参数------容器适配器,在上一篇博客中有

四 : 非类型模板参数
对于函数模板和类模板,模板参数并不局限于类型,普通值也可以作为模板

(1)非类型的类模板参数
//template<class T,size_t M>
template<class T, size_t M=10>//带缺省的模板参数
class SeqList
{
public:
	SeqList();
	~SeqList();
private:
	T _array[M];
	int _size;
};
void test()
{
	SeqList<int, 10>s1;
	SeqList<int>s2;
}

(2)非类型的函数模板参数
template <class T,int value>
T ADD(const T&x)
{
	return value + x;
}
(3)浮点数和类对象是不允许作为非类型模板参数的
   
template<class T,double Max>
template <class T,string name>


五: 模板的分离式编译

分离编译是指一个完整的程序或项目由若干个源文件共同实现,每个源文件单独编译生成目标文件,最后将该项目的所有目标文件链接成一个单一的可执行文件的过程每个.cpp源文件经过预处理,它所包含的.h文件的代码都会被展开到其中。再经过编译器的编译,汇编等过程,将该.cpp文件转变为.obj文件,这时此文件已将变成二进制文件,本身包含的就是二进制代码。这时,该文件还不一定能够执行,因为并不保证其中一定有main函数,或者该源文件中的函数可能引用了另一个源文件中定义的某个变量或者函数调用,又或者在程序中可能调用了某个库文件中的函数,等等。这些都要通过链接器将该项目中的所有目标文件连接成一个单一的可执行文件来解决。main.cpp包含的Template.h头文件只有对F1()函数的声明,所以在main.cpp中没有任何与F1()函数定义相关的代码,这里就会把F1()函数看作外部链接类型。在主函数调用F1()函数时,会产生如下图红框的call命令,当然这里的地址是一个虚假的地址。链接器在Template.obj文件中找到F1()函数的实现代码,将call F1()地址通过jmp指令切换成真正的F1函数地址。

Template.h

 

#pragma once
#include<iostream>
using namespace std;
void F1();
template<class T>
void F2(const T& x);

Template.cpp

#include"Template.h"
void F1()
{
	cout << "F1()" << endl;
}
template<class T>
void F2(const T& x)
{
	cout << "F2()" << endl;
}

Main.cpp

#include"Template.h"
int main()
{
	F1();
	F2(10);
	system("pause");
	return 0;
}

看上面程序,如果只调用普通函数F1可以成功运行,但是调F2模板函数就不行,F2不支持分离编译。

为什莫模板函数不支持分离编译?怎样解决呢?

原因:因为在template.cpp中没有实例化,不生成代码。在Main.cpp中实例化。但是在链接前是不交互的,因此链接时找不到(因为没有)出错。

在执行main函数的语句中,要调用void F2<int>(const int& x),链接器在main.obj中找不到void F2<int>(const int&x)的定义,因此会去Template.obj中找。大家都知道模板只有在被实例化才生成代码,而在template.cpp中并没有实例化。虽然在main.cpp中实例化。但在链接之前两个文件是不交互的,链接器在template.obj中找不到函数实现的二进制代码。因此链接时会出错。
解决办法:1.在template.cpp中显示实例化

 如下图:

显示实例化


2.把声明和定义都放在.h中

如下图:


分离编译的优点:哪个.cpp改变,才生成对应.o  (.cpp和.o)的时间是相同的,如果改变,。cpp时间就和.o不同
不分离编译:哪怕有一点点的改变,都要重新编译,浪费时间,资源。
六: 模板总结
优点:1.模板复用了代码,节省资源。
          2.增强代码灵活性
缺点:1.模板让代码变得凌乱复杂,不易维护,编译代码时间边长(实例化,类型推演)。
           2.出现模板编译错误时,错误信息凌乱,不易定位错误。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值