类模板的作用:建立一个通用类,类中的成员数据类型可以不具体指定,用一个虚拟的类型来代表
1. 基本语法
比如我们在创建一个类时,里面的成员数据类型有多种,且不确定,这时就可以使用类模板:
template<class NameType, class AgeType>
class person {
public:
AgeType age;
NameType name;
};
2. 类模板和函数模板的区别
- 类模板没有自动类型推导,需要指定类型
- 类模板在模板参数列表中可以有默认参数,比如:
template<class NameType, class AgeType = int> //当不显示指定年龄类型是int时,有默认参数类型也是可以的
3. 类模板中成员函数的创建时机
- 普通类中,成员函数一开始就可以创建
- 类模板中,成员函数在调用时才创建
4. 类模板对象做函数参数
- 指定传入类型
void function(person<string,int> &p1){
// to do something
}
- 参数模板化
template<class NameType, class AgeType>
void function(person<NameType,AgeType> &p1){
// to do something
}
-整个类模板化
让编译器自动推导传入类的类型
template<class T>
void function(T &p1){
// to do something
}
5. 类模板与继承
- 当子类继承的父类是一个类模板时,子类在声明时要指定出父类中的T类型
class father {
T money;
};
class son : public father<int> {
};
6. 类模板成员函数如何在类外实现
类内声明,类外实现,语法如下:
void father<int>::show() { // 普通函数的类外实现
cout << this->money << endl;
}
template<class T1>
father<T1>::father(T1 m) { // 构造函数的类外实现
this->money = m;
}
7. 类模板与友元
- 全局函数在类内实现,调用私有变量:
#include <iostream>
using namespace std;
template<class T>
class father {
friend void show(father<T> f) {
cout << f.money << endl;
}
private:
T money;
public:
father(T m) {
this->money = m;
}
};
int main() {
father<int> f(1);
show(f);
return 0;
}
- 全局函数在类外实现,调用私有变量:
需要让编译器提前知道函数模板的存在,要把该全局函数放在类的上方:
#include <iostream>
using namespace std;
template<class T> //让编译器提前知道有模板类的存在
class father;
template<class T> //让编译器提前知道有函数模板的存在
void show(father<T> f) {
cout << f.money << endl;
}
template<class T>
class father {
friend void show<>(father<T> f);
private:
T money;
public:
father(T m) {
this->money = m;
}
};
int main() {
father<int> f(1);
show(f);
return 0;
}