1.函数模板与类模板
1.1函数模板
1.1.1函数模板的基本语法
模板函数技术可以将类型参数化 编写代码时可以忽略类型
template<class T2,class T2> //每一个模板函数前面必须有此声明,只对第一个函数生效
返回值 函数名(T 形参,...)
{
函数体;
}
函数模板的两种使用方式:1、自动模式转换 2、显示的指定类型
1、自动模式转换
template<class T>
void MySwap(T &a,T &b)
{
T temp=a;
a=b;
b=temp;
}
int main
{
int a=1;
int b=2;
MySwap(a,b);//模板函数参数类型自动转换成int
double c=1.0;
double d=2.0;
MySwap(c,d);//模板函数参数类型自动转换成double
return 0;
}
2、显示的指定类型
template<class T>
void MySwap(T &a,T &b)
{
T temp=a;
a=b;
b=temp;
}
int main
{
int a=1;
int b=2;
MySwap<int>(a,b);//模板函数参数类型自动转换成int
double c=1.0;
double d=2.0;
MySwap<double>(c,d);//模板函数参数类型自动转换成double
return 0;
}
1.1.2函数模板作用示例
//int 类型函数
void MySwap(int &a,int &b)
{
int temp=a;
a=b;
b=temp;
}
//double类型函数
void MySwap(double &a,double &b)
{
double temp=a;
a=b;
b=temp;
}
//使用函数模板
template<class T>
void MySwap(T &a,T &b)
{
T temp=a;
a=b;
b=temp;
}
1.1.3函数模板与普通函数的区别
普通函数的参数可以进行隐式类型转换,模板函数严格匹配参数类型
//函数模板
template<class T>
int MySwap(T &a,T &b)
{
return a+b;
}
//普通函数
int MySwap(int a,char b)
{
return a+b;
}
int main
{
int a;
int b;
char c;
char d;
MySwap(a,b);//调用模板函数
MySwap(a,c);//调用普通函数
MySwap(c,a);//调用普通函数,进行了参数类型进行了隐式转换
}
1.1.4函数模板与普通函数一起调用的规则
- 函数模板可以像普通函数那样被重载
- C++编译器优先考虑普通函数
- 如果函数模板可以产生一个更好的匹配,那么选择模板
- 可以通过空模板实参列表的语法来限制编译器只能通过模板匹配
int main
{
MySwap<>(a,b);//强制使用模板函数
}
1.2类模板
1.2.1类模板的基本语法
template<class T>
class Person
{
public:
Person(T id,T age)
{
this->mAge=age;
this->mId=id;
}
public:
T mAge;
T mId;
}
void test()
{
//函数模板在使用时可以自动推导
//类模板必须显示指定类型
Person<int> p(10,20);
}
1.2.2类模板派生普通类
类模板派生普通类2种方式
1、指定父类类型
//父类
template<class T>
class Parent
{
类实现
}
//派生子类
class Son : public Parent<int>{};
2、子类使用类模板
//父类
template<class T>
class Parent
{
类实现
}
//子类
template<class T>
class Son :public Parent<T>{};
{
类实现
}
1.2.3类模板h和cpp分离编写问题
类模板h和cpp一般不可以分离编写
原因:
1、c++编译机制是各文件独立编译
2、模板函数需要编译两次,第一次不生成实例函数,第二次编译是在模板函数被调用时进行,生成实例函数
1.2.4类模板的static成员问题
template<class T>
class Person
{
public:
static int a;
}
//类外初始化
template<class T> Person<int>::a=0;
int main
{
Person<int> p1,p2,p3;
Person<char> pp1,pp2,pp3;
p1.a=10;
pp1.a=100;
cout<<p1.a<<p2.a<<p3.a<<endl;//输出为10 10 10
cout<<p1.a<<p2.a<<p3.a<<endl;//输出为100 100 100
return0;
}
//类模板是一个未实例化的类,静态成员不分配空间,当类模板实例化后会实例化成真实的类,每个类分别共享自己的静态成员