模板引入
当我们定义一个函数时,需要定义这个形参的数据类型,比如我们定义一个交换函数,如果我们想交换int 和 int double 与 double 类型的变量,就需要用函数重载写出两个相同的函数。
因此引入了模板,大大提高了代码复用性
模板的概念
模板就是建立通用的模具,大大提高复用性
模板类型
C++提供两种模板机制: 函数模板 和 类模板
语法
template<class A>
函数声明或定义
解释:
template 声明创建模板
class 可以用typename替换,表明其后面的符号是一种数据类型
A 通用的数据类型,名字可以替换,通常为大写字母(int double char 对象…)
函数模板
举例
有两种方式
1、自动类型判定
函数名(形参表)
2、显示指定类型
函数名<数据类型>(形参表)
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
template<typename A>
void Swap(A &a ,A &b)
{
A temp = a;
a = b;
b = temp;
}
int main() {
int a=10,b=20; //显示指定类型
Swap<int>(a,b);
cout<<a<<" "<<b<<endl;
a = 30 , b = 40; //自动类型判定
Swap(a,b);
cout<<a<<" "<<b<<endl;
double c=1.2,d=3.4;
Swap(c,d);
cout<<c<<" "<<d<<endl;
char e = 'a',f = 'b';
Swap(e,f);
cout<<e<<" "<<f<<endl;
return 0;
}
注意事项
1、自动类型判定,必须判定出与 通用数据类型(A) 一致的数据类型才能使用
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
template<class A>
void Swap(A &a ,A &b)
{
A temp = a;
a = b;
b = temp;
}
int main() {
int a = 30 , b = 40; //a,b都是int型 可以使用
Swap(a,b);
cout<<a<<" "<<b<<endl;
int a = 30;
double b = 40.5; //a是int型,b是double型 数据类型不同不可使用
Swap(a,b);
cout<<a<<" "<<b<<endl;
return 0;
}
2、模板不能独立使用,必须确定 通用数据类型(A) 的数据类型,才能使用
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
template<class A>
void Swap()
{
cout<<"Swap函数";
}
int main() {
Swap(); //定义模板后不能独立调用,会报错
Swap<int>(); //随意显式输入一个数据类型(A),就能调用了
return 0;
}
类模板
template<class T>
举例
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
template<class Name , class Age>
class Person
{
private:
Name m_Name;
Age m_Age;
public:
Person(Name name,Age age)
{
m_Name = name;
m_Age = age;
}
void showPerson()
{
cout<<"姓名:"<<m_Name<<endl;
cout<<"年龄:"<<m_Age;
}
};
int main() {
Person<string,int>p("张三",18); //编译器不能进行自动类型判定
p.showPerson();
return 0;
}
函数模板与类模板的区别
1、类模板没有自动类型判定
2、类模板在模板参数列表中可以有默认参数
创建时机
类模板中的成员函数和普通类中的成员函数的创建时机不同
- 普通类中的成员函数一开始就可以创建
- 类模板中的成员函数在调用时才创建
#include<iostream>
using namespace std;
class Person1
{
public:
void showPerson1()
{
cout<<"Person1"<<endl;
}
};
class Person2
{
public:
void showPerson2()
{
cout<<"Person2"<<endl;
}
};
template <class T>
class Class1
{
public:
T obj;
void fun1(){
obj.showPerson1();
}
void fun2(){
obj.showPerson2();
}
};
int main()
{
// 类名 <数据类型> 对象名
Class1<Person1>m; //对象也是一种数据类型
m.fun1();
Class1<Person2>n; //如果不声明数据类型而直接调用的话会报错
n.fun2();
return 0;
}
类模板对象做函数的参数
类模板实例化出对象,向函数传参的方式
传入方式
- 指定传入类型:直接显示对象的数据类型
- 参数模板化:将对象中的参数变为模板进行传递
- 整个类模板化:将对象类型模板化进行传递
示例
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
template<class Name , class Age>
class Person
{
private:
Name m_Name;
Age m_Age;
public:
Person(Name name,Age age)
{
m_Name = name;
m_Age = age;
}
void showPerson()
{
cout<<"姓名:"<<m_Name<<endl;
cout<<"年龄:"<<m_Age;
}
};
//1.指定传入类型(string,int)
void printPerson1(Person<string,int>&p)
{
p.showPerson();
}
//2.参数模板化
template<class T1,class T2>
void printPerson2(Person<T1,T2>&p)
{
p.showPerson();
}
//3.整个类模板化
template<class T>
void printPerson3(T &p)
{
p.showPerson();
cout<<endl<<typeid(T).name()<<endl;
}
int main() {
Person<string,int>p1("张三",18); //1.指定传入类型(string,int)
printPerson1(p1);
cout<<endl;
Person<string,int>p2("李四",20); //2.参数模板化
printPerson2(p2);
cout<<endl;
Person<string,int>p3("王五",22); //3.整个类模板化
printPerson3(p3);
return 0;
}
实际开发中 指定传入类型 最常用