一、类模板的定义
类模板是C++中一种特殊的模板,用于创建通用的类。通过类模板,我们可以定义一个通用的类,这个类可以接受不同类型的数据作为其成员或参数。在使用类模板时,我们需要指定具体的数据类型,编译器会根据指定的数据类型生成对应的类。
作用:建立一个通用类,类中的成员的数据类型是不指定的(不具体),用一个或者多个虚拟的类型来表达
二、类模板操作
语法
三、类模板和模板函数的区别
1、类模板只能显示指定类型的方式,而函数模板有自动类型推导的方式。
2、类模板中的模板参数列表可以有默认的参数,而函数模板则没有。
注:有默认值的情况下可以不用显示实例化。
代码示例:
cpp
#include <iostream>
using namespace std;
template <class NameType,class AgeType = int>//类型声明:不是类中有多少成员属性,看实际的类型种类
class Myclass{
public:
NameType name;
AgeType age;
Myclass(){}
Myclass(NameType name,AgeType age):name{name},age{age}{}
void print(){
cout<<"name:"<<name<<",age:"<<age<<endl;
}
};
int main()
{
Myclass<string,int> mc("aaa",18);//必须使用显式指定类型的方式来使用类模板
Myclass<string> mc1("bbb",15);//类模板中的模板参数列表可以指定默认参数
mc.print();
mc1.print();
return 0;
}
运行结果:
cpp
name:aaa,age:18
name:bbb,age:15
四、一般类模板的对象做函数参数有三种传入方式:
指定传入的类型:直接显示对象的数据类型
参数模板化:将对象中的参数变为模板进行传递(函数模板)。
整个类模板化:将这个对象的类型模板化进行传递(函数模板)。
cpp
#include <iostream>
using namespace std;
template <class NameType,class AgeType>
class Person{
public:
Person(){}
Person(NameType name,AgeType age):name{name},age{age}{}
NameType name;
AgeType age;
void printer()
{
cout<<"name:"<<name<<",age:"<<age<<endl;
}
};
//直接显示对象的数据类型
void print1(Person<string,int>&p)
{
p.printer();
}
//将对象中的参数变为模板进行传递(函数模板)
template<typename T1,typename T2>
void print2(Person<T1,T2>&p)
{
p.printer();
}
//将这个对象的类型模板化进行传递函数模板
template<typename T>
void print3(T &p)
{
p.printer();
}
int main()
{
Person <string,int>p("gaoyinjie",27);
print1(p);
print2(p);
print3(p);
return 0;
}
运行结果:
cpp
name:gaoyinjie,age:27
name:gaoyinjie,age:27
name:gaoyinjie,age:27
五、类模板继承
当子类继承父类是一个模板时,子类在声明时,需要指定父类中T的类型如果不指定,编译器就无法给子类分配内存,如果想灵活指定父类中T的类型,子类可以变为类模板
代码示例
cpp
#include <iostream>
using namespace std;
template<typename T>
class Base{
public:
T a;
};
//子类继承父类是一个模板时,子类在声明时需要指定父类中T的类型
class Son1:public Base<int>{
public:
Son1(){}
Son1(int a):Base{a}{}
};
// 子类模板中T1替代(指定)父类模板中的T
template<class T1, class T2>
class Son2 : public Base<T1> {
public:
T2 b;
};
int main()
{
Son1 s1(3);
cout<<s1.a<<endl;
Son2 <int,string>s2;
s2.a = 3;
s2.b = "zhangsan";
cout<<s2.a<<endl;
cout<<s2.b<<endl;
return 0;
}
运行结果:
3
3
zhangsan
六、类模板和友元
全局函数配合友元,类内实现(推荐)
cpp
template <class T1, class T2>
class Person{
// 全局函数配合友元的类内实现
friend void print(Person<T1,T2> & p){
cout << "姓名:" << p.name << ",年龄:" << p.age << endl;
}
private:
T1 name;
T2 age;
public:
Person(T1 name, T2 age){
this->name = name;
this->age = age;
}
};
int main(){
Person<string,int> p("Jim",18);
print(p);
return 0;
}
七、类模板特化
完全特化:将模板参数列表中所有的参数都确定化。
偏特化:任何针对模板参数进一步进行条件限制设计的特化版本。
代码示例:
cpp
#include <iostream>
#include <string>
using namespace std;
template<typename T>
class Comparator{
public:
T a;
T b;
Comparator(T a,T b)
{
this->a = a;
this->b = b;
}
T compare()
{
return a > b?a:b;
}
};
template<>
class Comparator<string>{
public:
string a;
string b;
Comparator(string a,string b):a{a},b{b}{}
string compare(){ //成员函数的实现应该和基础版的类模板不同
return a.length()>b.length()?a:b;
}
};
int main()
{
Comparator<int> c1(12,13);
cout<<"数的较大的值是:"<<c1.compare()<<endl;
Comparator<string> c2("aaab","dfdf");
cout<<"字符串更大的是:"<<c2.compare()<<endl;
return 0;
}
运行结果:
数的较大的值是:13
字符串更大的是:dfdf