一、基本使用
①通用类型用于成员变量
②通用类型用于成员函数的参数
③通用类型用于成员函数的返回值,获取成员变量
④通用类型用于成员函数的代码中
代码
#include <iostream>
using namespace std;
template <class T1,class T2>//类模板头部,通用类型用于类
class AA
{
public:
T1 m_a; //①通用类型用于成员变量
T2 m_b; //通用类型用于成员变量
AA(){} //默认构造函数
AA(T1 a,T2 b):m_a(a),m_b(b){} //②通用类型用于成员函数的参数
T1 geta() //③通用类型用于成员函数的返回类型,获取成员m_a的值
{
T1 a=2; //④通用类型用于成员函数的代码中
return m_a+a;
}
T2 getb() //通用类型用于成员函数的参数
{
T2 b=1; //通用类型用于成员函数的返回类型,获取成员
return m_b+b;
}
};
二、注意事项:
1)在创建对象的时候,必须显式指定具体的数据类型,不存在自动推导数据类型(函数模板可以自动推导数据类型,可以不显式指定);
代码
#include <iostream>
using namespace std;
template <class T1,class T2>//类模板头部,通用类型用于类
class AA
{
public:
T1 m_a; //①通用类型用于成员变量
T2 m_b; //通用类型用于成员变量
AA(){} //默认构造函数
AA(T1 a,T2 b):m_a(a),m_b(b){} //②通用类型用于成员函数的参数
T1 geta() //③通用类型用于成员函数的返回类型,获取成员m_a的值
{
T1 a=2; //④通用类型用于成员函数的代码中
return m_a+a;
}
T2 getb() //通用类型用于成员函数的参数
{
T2 b=1; //通用类型用于成员函数的返回类型,获取成员
return m_b+b;
}
};
int main()
{
AA<int,double>a;
a.m_a=20;
a.m_b=30;
cout<<"a.geta()="<<a.geta()<<endl;
cout<<"a.getb()="<<a.getb()<<endl;
return 0;
}
AA<int,double>a;//在<>填数据类型
在<>中填数据类型,告诉编译器分别用int、double取代T1、T2,帮我生成一个类的定义,然后用这个类创建对象a;
运行结果
2)使用类模板时,数据类型必须适应类模板中的代码;
代码
#include <iostream>
using namespace std;
template <class T1,class T2>//类模板头部,通用类型用于类
class AA
{
public:
T1 m_a; //①通用类型用于成员变量
T2 m_b; //通用类型用于成员变量
AA(){} //默认构造函数
AA(T1 a,T2 b):m_a(a),m_b(b){} //②通用类型用于成员函数的参数
T1 geta() //③通用类型用于成员函数的返回类型,获取成员m_a的值
{
T1 a=2; //④通用类型用于成员函数的代码中
return m_a+a;
}
T2 getb() //通用类型用于成员函数的参数
{
T2 b="ss"; //通用类型用于成员函数的返回类型,获取成员
return m_b+b;
}
};
int main()
{
AA<int,string>a;
a.m_a=20;
a.m_b="bbb";
cout<<"a.geta()="<<a.geta()<<endl;
cout<<"a.getb()="<<a.getb()<<endl;
return 0;
}
AA<int,string>a;//在<>中填数据类型
此时T2为string类型,原本的getb()中定义的临时变量b的赋值则需改变为string类型的“ss”;
运行结果
3)类模板可以为通用数据类型指定缺省的数据类型(C++11标准的函数模板也可以,意义不大;
代码
#include <iostream>
using namespace std;
template <class T1,class T2=string>//类模板头部,通用类型用于类 指定缺省类型
class AA
{
public:
T1 m_a; //①通用类型用于成员变量
T2 m_b; //通用类型用于成员变量
AA(){} //默认构造函数
AA(T1 a,T2 b):m_a(a),m_b(b){} //②通用类型用于成员函数的参数
T1 geta() //③通用类型用于成员函数的返回类型,获取成员m_a的值
{
T1 a=2; //④通用类型用于成员函数的代码中
return m_a+a;
}
T2 getb() //通用类型用于成员函数的参数
{
T2 b="ss"; //通用类型用于成员函数的返回类型,获取成员
return m_b+b;
}
};
int main()
{
AA<int>a;//缺省数据类型
a.m_a=20;
a.m_b="bbb";
cout<<"a.geta()="<<a.geta()<<endl;
cout<<"a.getb()="<<a.getb()<<endl;
return 0;
}
在声明类头部时声明通用数据类型指定缺省的数据类型string,
template <class T1,class T2=string>
在定义对象时缺省一个数据类型,类模板会自动指定缺省数据类型
AA<int>a;
运行结果不变
4)模板类的成员函数可以在类外实现;
代码
#include <iostream>
using namespace std;
template <class T1,class T2=string>//类模板头部,通用类型用于类
class AA
{
public:
T1 m_a; //①通用类型用于成员变量
T2 m_b; //通用类型用于成员变量
AA(){} //默认构造函数
AA(T1 a,T2 b):m_a(a),m_b(b){} //②通用类型用于成员函数的参数
T1 geta() //③通用类型用于成员函数的返回类型,获取成员m_a的值
{
T1 a=2; //④通用类型用于成员函数的代码中
return m_a+a;
}
T2 getb(); //通用类型用于成员函数的参数
};
template <class T1,class T2>//不能在类外部指定默认模板参数template <class T1,class T2=string>
T2 AA<T1,T2>::getb() //通用类型用于成员函数的参数
{
T2 b="ss"; //通用类型用于成员函数的返回类型,获取成员
return m_b+b;
}
int main()
{
AA<int>a;
a.m_a=20;
a.m_b="bbb";
cout<<"a.geta()="<<a.geta()<<endl;
cout<<"a.getb()="<<a.getb()<<endl;
return 0;
}
在类的内部声明成员函数
T2 getb(); //通用类型用于成员函数的参数
在类外定义成员函数,要注意不可以在类外部指定默认模板参数,且成员函数的定义也需要带上类模板的头部
template <class T1,class T2> //不能在类外部指定默认模板参数template <class T1,class T2=string>
T2 AA<T1,T2>::getb() //通用类型用于成员函数的参数
{
T2 b="ss"; //通用类型用于成员函数的返回类型,获取成员
return m_b+b;
}
运行结果
5)可以用new创建类模板对象;
代码
#include <iostream>
using namespace std;
template <class T1,class T2=string>//类模板头部,通用类型用于类
class AA
{
public:
T1 m_a; //①通用类型用于成员变量
T2 m_b; //通用类型用于成员变量
AA(){} //默认构造函数
AA(T1 a,T2 b):m_a(a),m_b(b){} //②通用类型用于成员函数的参数
T1 geta() //③通用类型用于成员函数的返回类型,获取成员m_a的值
{
T1 a=2; //④通用类型用于成员函数的代码中
return m_a+a;
}
T2 getb(); //通用类型用于成员函数的参数
};
template <class T1,class T2>//不能在类外部指定默认模板参数template <class T1,class T2=string>
T2 AA<T1,T2>::getb() //通用类型用于成员函数的参数
{
T2 b="ss"; //通用类型用于成员函数的返回类型,获取成员
return m_b+b;
}
int main()
{
//AA<int,string>*a=new AA<int,string>;//调用默认构造函数
AA<int,string>*a=new AA<int,string>(3,"bbb");//调用带两个参数构造函数
cout<<"a->geta()="<<a->geta()<<endl;
cout<<"a->getb()="<<a->getb()<<endl;
delete a;
return 0;
}
用模板类AA创建对象a
//AA<int,string>*a=new AA<int,string>;//调用默认构造函数
AA<int,string>*a=new AA<int,string>(3,"bbb");//调用带两个参数构造函数
AA是类模板名,不是一种具体的数据类型,必须在指定了参数类型才可以定义类对象
AA<int,string>才是类名,具体的数据类型
运行结果
6)在程序中,模板类的成员函数使用了才会创建,不适用就不会创建