类模板基本语法
// 定义 template<class T> class Base { T m1; }; // 调用 Base<int> base;
类模板与函数模板的区别
- 类模板没有自动类型推导的使用方式,必须显示指定类型
- 类模板在模板参数列表中可以有默认参数
类模板中成员函数创建时机
- 普通类中的成员函数,一开始就可以创建
- 类模板中的成员函数在调用时才创建
类模板对象做函数参数
- 指定传入的类型(最常用)
- 参数模板化
- 整个类模板化
#include<iostream> using namespace std; template<class NameType, class AgeType> class Person { public: Person(NameType name, AgeType age) { this->m_name = name; this->m_age = age; } void showPerson() { cout << "name: " << this->m_name << " age: " << this->m_age << endl; } NameType m_name; AgeType m_age; }; // 指定传入类型 void showPerson1(Person<string, int> &p) { p.showPerson(); } // 参数模板化 template<class T1, class T2> void showPerson2(Person<T1, T2>& p) { p.showPerson(); } // 整个类模板化 template<class T> void showPerson3(T& p) { p.showPerson(); } int main() { Person<string, int> p("张三", 999); showPerson1(p); showPerson2(p); showPerson3(p); return 0; }
类模板与继承
- 当父类是类模板时,子类声明时要指定父类中的模板参数类型
- 如果不指定,编译器无法分配内存
- 如果想灵活指定父类中的模板参数类型,子类就必须也变为类模板
#include<iostream> using namespace std; template<class T> class Base { T m1; }; // 子类声明中指定父类中的模板类型 class Son1 : public Base<int> { public: void show() { cout << "Son 1 is created" << endl; } }; // 将子类也变为模板类 template<class T1, class T2> class Son2 :public Base<T2> { T1 m2; public: void show() { cout << "Son 2 is created" << endl; } }; int main() { Son1 s1; s1.show(); Son2<int, char> s2; s2.show(); return 0; }
类模板成员函数类外实现
template<class T1, class T2> void Person<T1, T2>::showPerson() { cout << "person is shown" << endl; }
类模板份文件编写
需要解决类模板中成员函数在调用是才创建,因此编译器可能链接不到的问题。解决方案如下:
- 将头文件和源文件合并成一个 .hpp 文件 (推荐)
- 直接包 include 文件(.cpp 文件)
类模板和友元
- 全局函数,类内实现(推荐)
- 全局函数,类外实现(很复杂,不推荐)
template<class NameType, class AgeType> class Person { friend void showPerson(Person<NameType, AgeType> &p) { cout << "name: " << p.m_name << " age: " << p.m_age << endl; } public: Person(NameType name, AgeType age) { this->m_name = name; this->m_age = age; } private: NameType m_name; AgeType m_age; };