这个博客是关于一些模板的知识。在C++的提高中,我要用一些篇幅来讲述一下模板的相关知识。
话不多说,直接开始。
1、函数模板的基本用法
模板的概念:
模板就是建立通用的模具,通过模板可以大大提高代码的复用性
模板的特点:
- 1.模板不可以直接使用,它只是一个框架
- 2.模板的通用并不是万能
模板的应用体现了C++的泛型编程编程思想。
函数模板语法
函数模板作用:
建立一个通用函数,其函数返回值类型和形参类型可以不具体制定,用一个虚拟的类型来代表。
解释一下,比如一个函数的声明
void func(int a)
模板就是,不用具体写出函数的返回值(void),也不用具体写出形参的类型(int a),使用的时候再去具体的要求它。这就叫用虚拟的类型来表示。而返回值和形参类型怎么办呢?我们可以用“T”来表示。先虚拟出来一个函数,具体使用的时候,再去把返回值T定义为void等形式,形参列表T定义为int、string、float等类型。
语法:
template<typename T>
解释:
- template — 声明创建模板
- typename — 表面其后面的符号是一种数据类型,可以用class代替
- T — 通用的数据类型,名称可以替换,通常为大写字母
我们直接上代码
首先先用传统的函数声明定义来进行两个数的交换,代码放在下边。
#include<iostream>
using namespace std;
void swapInt(int & a,int & b)//使用引用,直接交换本体。
{
int temp = a;
a = b;
b = temp;
}
void swapFloat(double & a,double & b)
{
double temp = a;
a = b;
b = temp;
}
int main()
{
int a = 10;
int b = 20;
cout << "交换前的a= " << a << " , " << "交换前的b= " << b << endl;
swapInt(a, b);
cout << "交换后的a= " << a << " , " << "交换后的b= " << b << endl;
cout << "---------------------------------------------" << endl;
double c = 10.2;
double d = 15.8;
cout << "交换前的c= " << c << " , " << "交换前的d= " << d << endl;
swapFloat(c, d);
cout << "交换后的c= " << c << " , " << "交换后的d= " << d << endl;
system("pause");
return 0;
}
显示一下结果
交换前的a= 10 , 交换前的b= 20
交换后的a= 20 , 交换后的b= 10
---------------------------------------------
交换前的c= 10.2 , 交换前的d= 15.8
交换后的c= 15.8 , 交换后的d= 10.2
请按任意键继续. . .
我们发现,想实现两个数的交换,不同的数据类型需要不同的函数实现,这就造成了代码的冗余。怎么才能提高代码的复用性呢?
通过观察,这两个函数是有相通性的。逻辑非常类似,只是函数的返回值和形参不同。
基于此,我们引入了模板。
#include<iostream>
using namespace std;
plate<typename T>
//1.typename可以用class来代替
//2.声明一个模板,告诉编译器后边的T不要报错,因为他是一个通用的数据类型。
void mySwap(T & num1, T & num2)
{
T temp = num1;
num1 = num2;
num2 = temp;
}
int main()
{
int a = 10;
int b = 20;
cout << "交换前的a= " << a << " , " << "交换前的b= " << b << endl;
//利用模板实现交换
//1、自动类型推导
mySwap(a, b);
cout << "交换后的a= " << a << " , " << "交换后的b= " << b << endl;
cout << "---------------------------------------------" << endl;
double c = 1.1;
double d = 2.2;
cout << "交换前的c= " << c << " , " << "交换前的d= " << d << endl;
//2、显示指定类型
mySwap<double>(c, d);
cout << "交换后的c= " << c << " , " << "交换后的d= " << d << endl;
system("pause");
return 0;
}
是不是代码的复写性提高了不少。只用了一个模板就统一了上边代码段两个函数。
总结:
- 函数模板利用关键字 template
- 使用函数模板有两种方式:自动类型推导、显示指定类型
- 模板的目的是为了提高复用性,将类型参数化
2、函数模板的注意事项
注意事项:
- 自动类型推导,必须推导出一致的数据类型T,才可以使用
- 模板必须要确定出T的数据类型,才可以使用
直接上代码:
#include<iostream>
using namespace std;
template<typename T>
//1、自动类型推导,必须推导出一致的数据类型T,才可以使用
void mySwap(T & num1, T & num2)
{
T temp = num1;
num1 = num2;
num2 = temp;
}
void test01()
{
int a = 10;
int b = 20;
mySwap(a, b);//正确!
char c= 'c';
// mySwap(a, c); //错误
}
// 2、模板必须要确定出T的数据类型,才可以使用
template<typename T>
void func()
{
cout << "func 调用" << endl;
}
void test02()
{
//func(); //错误,模板不能独立使用,必须确定出T的类型
func<int>(); //利用显示指定类型的方式,给T一个类型,才可以使用该模板
}
int main()
{
test01();
test02();
system("pause");
return 0;
}
总结:
- 使用模板时必须确定出通用数据类型T,并且能够推导出一致的类型