简介:C++类模板提供一种参考范式,能够按照需要生成想要的数据类型。
1、类模板
类模板是创建类的模板,根据代码编写时传递的参数类型生成不同的类结构体,这些类的成员名称相同,但是指向的数据类型是不同的。通用类型可以替代:成员方法的返回值、成员方法函数体里面的数据类型、成员属性的类型。
#include<iostream>
using namespace std;
typedef struct student {
int age;
string name;
} S1, S2;//两个别名
template<class T1, class T2>
class PC {
public:
//通用类型用于函数返回值
T1 showinfo() {
T2 a;//通用类型用于函数体变量
cout << 666;
}
//通用类型用于成员变量
T2 a;
int b=3;
S1 s1={18,"mmd"};
};
int main() {
PC<int, float> pc1;//括号法调用默认构造
cout << pc1.s1.age;
};
此外,由于类是自定义的数据类型,在运行时无法临时生成,所以在编译之前必须要生成这些有类模板类对象。也就是类模板必须显示的指定参数类型并创建。
下面是类模板的一些注意点:
- 创建对象时,必须指定类模板的参数类型;
- 类方法里面的数据操作必须满足指定的参数类型;
- 类模板可以给类型参数指定默认类型;
#include<iostream>
using namespace std;
typedef struct student {
int age;
string name;
} S1, S2;//两个别名
template<class T1, class T2=float>//指定T2为float
class PC {
public:
//通用类型用于函数返回值
T1 showinfo() {
T2 a;//通用类型用于函数体变量
cout << 666;
}
//通用类型用于成员变量
T2 a;
int b=3;
S1 s1={18,"mmd"};
};
int main() {
PC<int> pc1;//括号法调用默认构造
cout << pc1.s1.age;
};
- 模板类的成员函数可以类里面声明,类外实现
#include<iostream>
using namespace std;
typedef struct student {
int age;
string name;
} S1, S2;//两个别名
template<class T1, class T2 = float> //指定T2为float
class PC {
public:
//通用类型用于函数返回值
T1 showinfo();
};
template<class T1, class T2> //类外实现不需要指定默认类型,因为类模板已经给了
T1 PC<T1,T2>::showinfo(){
cout << 666;
return 0;
};
int main() {
PC<int> pc1;//括号法调用默认构造
pc1.showinfo();
};
- 使用new关键字创建模板类对象,PC<int>就是一个类对象。
#include<iostream>
using namespace std;
typedef struct student {
int age;
string name;
} S1, S2;//两个别名
template<class T1, class T2 = float> //指定T2为float
class PC {
public:
int a;
//通用类型用于函数返回值
T1 showinfo();
PC(){};
PC(int a) {
this->a = a;
};
};
template<class T1, class T2> //类外实现不需要指定默认类型,因为类模板已经给了
T1 PC<T1, T2>::showinfo() {
cout << 666;
return 0;
};
int main() {
PC<int>* pc1 = new PC<int>;//使用new创建一个堆区的对象,调用默认构造
pc1->showinfo();
PC<int>* pc2 = new PC<int>(3);//使用new创建一个堆区的对象,调用带参数构造
cout<<pc2->a;
delete pc1;delete pc2;
};
- 模板类里面如果存在成员方法使用了参数类型,如果这个成员方法没有被调用那么就不会生成这个函数对象。
2、类模板的编写方法
类模板实际上就是数据类型参数化,当我们编写模板类的时候,最好遵循下面的步骤:
- 编写一个具体类型的类;
- 调试类代码,确保没有问题;
- 将具体类型的类修改为模板类;
3、非通用类型参数
这种做法就是向模板进行实际数据的传递。这种参数可以使用默认值代替,类生成时传递过去的参数需要使用常量表达式计算得到,类里面无法修改该参数。
4、模板类的继承
模板类的继承分为下面的几种:
- 模板类继承普通类(新类是一个模板)
- 普通类继承模板类(新类是一个模板类)
- 模板类继承模板类(新类仍然是一个模板)
- 普通类继承模板类的实例类(新类是一个普通类)
- 模板类继承模板类的实例类(新类仍然是一个模板)
总结:如果最终的类要求是普通类,那么就得明确这个新类里面所有的类型参数。否则就得变成类模板。此时模板形参可以放到继承方式的类里面。
5、模板类对象作为函数参数
当模板的参数指定之后,就会生成一个类,也就是一种数据类型。由于C++是强类型语言,需要显式的指定变量类型,所有类模板对象也是有类型的的。
针对每一种模板实例类类型,单独写一个函数处理这种类型的数据即可。如果某一系列类模板具有相同的动作和行为,那么则可以将函数模板化或者类模板化。