目录
一、函数模板
二、类模板?
一、函数模板
1.作用:
建立一个通用函数,其函数的返回值类型可以不具体定制,用一个虚拟类型代替
2.语法:
template<typename T> //函数声明或者定义 //template---声明创建函数模板 //typename---表明其后的符号是一种数据类型,可以用class代替 //T--- 通用数据类型 ?虚拟类型 可以换名称(H\J\...)
3.示例:?实现两个数据交换
?????????通常:
#include<iostream>
using namespace std;
//交换整型数据
void swapInt(int& a, int &b)//引用的方式交换
{
int temp;
temp = a;
a = b;
b = temp;
}
//交换双精度类型
void swapDouble(double& a, double& b)//引用的方式交换
{
double temp;
temp = a;
a = b;
b = temp;
}
void test01()
{
int x = 20;
int y = 30;
swapInt(x, y);
cout << "x = " << x << endl;
cout << "y = " << y << endl;
double m = 3.1415;
double n = 2.1817;
swapDouble(m, n);
cout << "m = " << m << endl;
cout << "n = " << n << endl;
}
int main()
{
test01();
return 0;
}
数据类型有很多种,相交换一种类型,就要写一次函数岂不是很麻烦?
观察两个交换函数有很多相似之处,为何不做一个模板(先不告诉交换什么类型的函数)
????????函数模板:
#include<iostream>
using namespace std;
//函数模板
template <typename T>
//声明一个模板,告诉编译器在后面的代码中如果遇见了T不要报错,T就是一个模板
void m_swap(T& a, T& b)//引用的方式交换
{
T temp;
temp = a;
a = b;
b = temp;
}
void test01()
{
int x = 20;
int y = 30;
//模板使用方式一
//1.自动类型推导
m_swap(x, y);
cout << "x = " << x << endl;
cout << "y = " << y << endl;
double m = 3.1415;
double n = 2.1817;
//模板使用方式二
//2.显示指定类型
m_swap<double>(m, n);//同理,上一个也可以写成m_swap<int>(x, y);
cout << "m = " << m << endl;
cout << "n = " << n << endl;
}
int main()
{
test01();
return 0;
}
????????两次运行结果:(相同)?
4.总结:
? ? ? ?函数模板关键字template;
???????使用模板的两种方式:自动类型推导,显式指定类型;
???????函数模板提高复用性,将类型参数化;
5.注意事项:
? ? ? ? 自动类型推导,必须推导出一致的数据类型T才可以使用;
错误案例:
int x = 20; ?char c = 'c'; ?m_swap(x, c);//编译器无法推导出到底是哪一个类型
? ? ? ? 模板必须推导出T的数据类型才可以使用;
//错误案例:
template <typename T>//声明了函数模板,却没有推导T类型 void test01() { ?? ?cout << "调用函数text01()" << endl; } void test02() { ?? ?test01();//想要使程序运行可以改成?test01<int>();//其他类型野性 } int main() { ?? ?test02(); ?? ?return 0; }
二、类模板?
1.语法:与函数模板相同
2.示例:
#include<iostream>
#include<string>
using namespace std;
template <class NameT,class AgeT>//这里的class与类的class不同
class Person
{
public:
Person(NameT name, AgeT age)
{
m_name = name;
m_age = age;
}
void showPerson()
{
cout << "name:" << this->m_name << " age:" << this->m_age << endl;
}
NameT m_name;//sting m_name
AgeT m_age;//int m_age
};
void test01()
{
Person<string, int>p1("Tony", 15);
p1.showPerson();
}
int main()
{
test01();
return 0;
}
3.类模板与函数模板区别
? ? ? ? a.类模板没有自动类型推导使用方式
void test01()
{
Person p("Tony",15)//错误?
}
? ? ? ? b.类模板在模板参数列表中可以有默认参数
template <class NameT,class AgeT = int>
... ...
void test01()
{
Person<string>p("Tony",15)//上面有默认参数类型,可以不写,函数模板不可以有
}
4.类模板中成员函数创建时机
?普通类中成员函数一开始就可以创建
类模板中成员函数在调用时才创建
5.类模板对象做函数参数
? ? ? ? 三类(补充:使用typeid(变量或类型).name()来获取常量或变量的类型)
#include<iostream>
#include<string>
#include<typeinfo>
using namespace std;
template <class T1,class T2>
class Person
{
public:
T1 m_name;
T2 m_age;
Person(T1 name, T2 age)
{
this->m_name = name;
this->m_age = age;
}
void showPerson()
{
cout << "name:" << this->m_name << " age:" << this->m_age << endl;
}
};
//1.指定传入类型
void test01()
{
Person<string, int>p1("Tony", 15);
p1.showPerson();
}
void printPerson1(Person<string, int>&p1)
{
p1.showPerson();
}
//2.数据模板化
template <class T1, class T2>
void printPerson2(Person<T1,T2>&p2)
{
p2.showPerson();
cout << "T1的类型:" << typeid(T1).name() << endl;
cout << "T2的类型:" << typeid(T2).name() << endl;
}
void test02()
{
Person<string, int>p2("Marry", 14);
printPerson2(p2);
}
//3.整个类模板化
template <class T>
void printPerson3(T &p3)
{
p3.showPerson(); cout << "T的类型:" << typeid(T).name() << endl;
}
void test03()
{
Person<string, int>p3("jick", 17);
printPerson3(p3);
}
int main()
{
test01();
test02();
test03();
return 0;
}
结果?
? ? ? ?来自b站网友的理解:假设现在有一列车,你有这列车的车票,车票上写了该列车对应的车号(类成员)和出发时间(成员的对应信息),然后车站有三个站口,第一个站口限定了只能通过有该车次和该时间段的车票的人,即设定好的成员参数,这是第一种。第三个站口只要你有车票就能通过,即不限定车次和时间,这就是类模板作为参数,这就是第三种的意思
|