OOP之模板(template)

C++ 模板

1. 模板的概念

  • 模板是C++较新的技术,是实现代码重用的重要工具;
  • 模板——是类(结构)或者操作进行类型参数化后的样板,是C++实现代码重用机制的一种工具;
  • 模板的声明——由关键字template声明,模板描述了一个类或函数的通用形式,编译器以类型参数化来进行支持;

例如:

int abs(int value) 			//求整型的绝对值
{
	return value>0?value:-value;
}

double abs(double value)	//求double型的绝对值
{
	return value>0?value:-value;
}

这两个函数,功能几乎一样,只是返回值和参数不一样。C++提供了函数模板的功能来简化我们对这种情况的表达:

template<class T>
T abs(T value)
{
    return value>0?value:-value;
}

其中T代表函数模板中要使用的通用类型,在函数的调用过程中,T被具体化。

  • C++中模板有两类:函数模板和类模板
    • 类模板:表示一组类(称为模板类)
    • 函数模板:操作不同类型的对象

2. 函数模板与模板函数

2.1 函数模板的声明
template <class Type> 
返回类型 函数名(参数表) 
{ 
	//使用Type的函数体 
}
或者
template<typename 类型参数>
返回类型 函数名(模板形参表) 
{ 
	//函数体 
}

举个栗子

#include <iostream>
using namespace std;

//函数模板:模板的定义
template<class T>
T my_max(T x,T y)
{
    return (x>y)?x:y;
}

int main()
{
    int a = 6,b=8;
    float c = 8.5,d=2.2;
    double e = 21.12,f = 145.98;
    char g = 'z',h = 'm';

    cout << my_max(a,b) <<endl; //根据传入的参数类型 实例化模板函数max(int,int)
    cout << my_max(c,d) <<endl; //根据传入的参数类型 实例化模板函数max(float,float)
    cout << my_max(e,f) <<endl; //根据传入的参数类型 实例化模板函数max(double,double)
    cout << my_max(g,h) <<endl; //根据传入的参数类型 实例化模板函数max(char,char)
    return 0;
}

2.2 由函数模板生成模板函数
  • 函数模板不是函数,不对应可执行代码。其定义是对一类函数的描述,只有实例化为模板函数后才能被执行。
  • 函数模板实例化时,编译系统根据函数调用时的实参类型,生成与之相对应的重载函数即模板函数。
  • 带有template的内容是函数模板,编译器生成的是模板函数。

举两个例子

求幂
#include <iostream>
using namespace std;

template <class T>
T Power(T a,int exp)	//求幂
{
    T ans = a;
    while(--exp>0) ans *= a;
    return ans;
}

int main()
{
    cout <<"3 ^ 5= " <<Power(3 ,5) <<endl;
    cout <<"1.1^2= " <<Power(1.1,2)<<endl;
    return 0;
}
顺序查找
#include <iostream>

using namespace std;
template <class T>
int sequentialSearch(T a[],const T&k,int n)
{
    int i=0;
    while(k!=a[i] && i<=n-1) i++;
    if(i>n-1) i=-1;
    return i;
}

int main()
{
    int i[] = {3,2,5,0,-1,7};
    double d[] = {3.3,2.1,0.3,1.5,10.6,5.2};
    char * c = "zju";

    cout << sequentialSearch(i,15,6) <<endl;
    cout << sequentialSearch(d,3.3,5) <<endl;
    cout << sequentialSearch(c,'j',3) <<endl;
    return 0;
}
2.3 模板函数重载的调用顺序

在C++中,函数模板与同名的非模板函数重载时,调用的顺序遵循下述约定:

  1. 寻找一个参数完全匹配的函数,如果找到就调用它。
  2. 寻找一个函数模板,将其实例化,产生一个匹配的模板函数。若找到了,就调用它。
  3. 若 1和2 都失败,寻找低一级的对函数的重载方法。例如通过类型转换可产生参数匹配等,若找到了,就调用它。
  4. 若 1,2,3 均未找到匹配的函数,则是一错误的调用。如果在第1步有多于一个的选择,那么这个调用是意义不明确的,是一个错误调用。
2.4 函数模板的异常处理

实例化T的各模板实参之间必须保持完全一致的类型,否则会发生错误。例如:

template<class T>
T my_max(T x,T y)
{
    return (x>y)?x:y;
}

void fun(int a,char c){
	my_max (a,a);
	my_max (c,c);
	my_max (a,c);		//error
	my_max (c,a);		//error
}

错误原因:编译器无法根据不一致类型生成相应模板函数。

  • 解决这个问题有以下两种方法:
    • 采用强制类型转换,如:my_max(i, int(c));
    • 用非模板函数重载函数模板,即定义一个完整的非模版函数 如:int my_max(int i, char c) { … }

3. 类模板和模板类

3.1 类模板的定义
template <class Type> 
class ClassName 
{ 
	//类的定义体 
};template <typename Type> 
class ClassName 
{ 
	//具体内容 
};

调用形式: ClassName<类型实参表> object
模板类是类模板对某一特定类型的实例。类模板代表了一类类,模板类表示某一具体的类。

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值