C++中的类模板是一种通用的类定义,它可以用于创建可以适应不同类型的对象。类模板是一种参数化的类,它可以根据不同的模板参数创建多个具体的类。
类模板的定义包含一个或多个模板参数,这些参数可以用于指定类中的类型、常量或其他模板参数。在使用类模板时,我们需要提供实际的模板参数,这些参数将用于实例化具体的类。
类模板语法
template<typename T>
类
-
template --- 声明创建模板
-
typename --- 表面后面的符号其实是一种数据类型,可以用class代替
-
T 通用数据类型,名称可以替换,一般都用T
template<class NameType,class AgeType>
class Person{
public:
Person(NameType name,AgeType age){
this->name = name;
this->age = age;
}
void showPerson(){
cout << "name:" << this.name << "age:" << this.age << endl;
}
NameType name;
AgeType age;
}
void test(){
Person<string,int> p1("tang",20);
p1.showPerson();
}
类模板和函数模板区别
-
类模板没有自动类型推导使用方式
-
类模板在模板参数列表中可以有默认参数,而函数模板不行
Person p1("tang",20); //报错,无自动类型推导
Person<string,int> p1("tang",20); //正确
//定义时给默认参数
template<class NameType,class AgeType = int>
Person p1<string>("tang",20); //不报错,后面默认当作int类型
类模板中的成员函数并不是一开始就创建,而是调用时才去创建,这在分文件编写时就显得很关键
类模板对象做函数参数
类模板参数对象做函数参数有三种形式:
我先定义一个类模板
template<class T1,class T2>
class Person{
public:
Person(T1 name,T2 age){
this->name = name;
this->age = age;
}
void show(){
cout << "name:" << this.name << "age:" << this.age << endl;
}
T1 name;
T2 age;
};
void test(){
Person<string,int> p('tang',20);
showPerson(p);
}
-
指定传入类型 使用比较广泛
void showPerson(Person<string,name> &p){
p.show();
}
-
参数模板化
template<class T1,class T2>
void showPerson(Person<T1,T2>& p){
p.show();
}
-
整个类都模板化
template<class T>
void showPerson(T &p){ //让他自己推导
p.show();
}
类模板与继承
-
当子类继承的父类是一个类模板时,子类在声明的时候要指定出父类中T的类型
-
如果不指定,编译器无法给子类分配内存
-
如果想灵活指定父类T的类型,子类也要变成类模板
template<class T>
class Base{
public:
T a;
};
//C++编译器要给子类分配内存,必须知道父类中T的类型才能分配并向下继承
class Son:public Base<int>{ //必须指定一个类型,否则无法继承
public:
};
//或者也变成模板
template<class T1,class T2>
class Son2:public Base<T2>{ //T2为继承的,T1是自己的
T1 obj;
};
Son2<int,char> S2;
类模板成员函数类外实现
template<class T1,class T2>
class Person{
public:
T1 name;
T2 age;
Person(T1 name,T2 age);
void show();
};
//构造函数类外实现
template<class T1,class T2>
Person<T1,T2>::Person(T1 name,T2 age){
this->name = name;
this->age = age;
}
//成员函数类外实现
template<class T1,class T2>
Person<T1,T2>::show(){
cout << "name:" << this.name << "age:" << this.age << endl;
}
类模板份文件编写
-
第一种解决办法,直接包含源文件
-
第二种解决办法将.h和.cpp内容写到一起并将后缀名改为.hpp文件
一般使用第二种
类模板与友元
一般使用类内实现,类外实现形式比较复杂
//对于全局函数类外实现,还需要加前置声明才能让编译器知道。。。
template<class T1,class T2>
class Person;
//函数实现也得放在友元定义之前
template<class T1,class T2>
void printPerson2(Person<T1,T2> p){
cout << this.name << this.age << endl;
}
template<class T1,class T2>
class Person{
//全局函数类内实现
friend void printPerson(Person<T1,T2> p){
cout << this.name << this.age << endl;
}
friend void printPerson2<>(Person<T1,T2> p); //全局函数类外实现,在类内声明为友元函数
//必须加一个空参数列表,才能和外面函数模板一致,否则这里定义的就是一个普通函数而不是函数模板
private:
T1 name;
T2 age;
public:
Person(T1 name,T2 age){
this->name = name;
this->age = age;
}
};
本文详细介绍了C++中的类模板,包括其基本概念、模板参数的使用、类模板与函数模板的区别、类模板继承、友元以及在分文件编写中的处理方法。
2269

被折叠的 条评论
为什么被折叠?



