01 类模板语法
#includeusing namespace std; //类模板 template class Person { public: NameType m_Name; AgeType m_Age; 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; } }; void _01Test01() { Person p("Tom", 18);//< >中就相当于模板形参列表 p.ShowPerson(); } void main() { _01Test01(); }
02 类模板与函数模板的区别
//1、类模板没有自动类型推导的使用方式
//2、类模板在模板参数列表中可以有默认类型参数 函数模板不可以使用默认类型参数
#includeusing namespace std; #include //类模板与函数模板的区别 //1、类模板没有自动类型推导的使用方式 //2、类模板在模板参数列表中可以有默认类型参数 函数模板不可以使用默认类型参数 template class _02Person { public: NameType m_Name; AgeType m_Age; public: _02Person(NameType name, AgeType age) { this->m_Name = name; this->m_Age = age; } void ShowPerson() { cout << "name:" << this->m_Name << " age:" << this->m_Age << endl; } }; //1、类模板没有自动类型推导的使用方式 void _02Test01() { //_02Person p("Tom", 19);//报错 类模板中没有自动类型推导 _02Person p("Tom", 19); p.ShowPerson(); } //2、类模板在模板参数列表中可以有默认类型参数 void _02Test02() { //使类模板参数列表中的AgeType默认等于int _02Person p1("Tony", 20); p1.ShowPerson(); _02Person p2("Jack", "22"); p2.ShowPerson(); } void main() { //_02Test01(); _02Test02(); }
03 类模板中成员函数的创建时机
//类模板中的成员函数并不是一开始就创建的 而是在模板调用时才创建
#includeusing namespace std; //类模板中成员函数的创建时机 //类模板中的成员函数并不是一开始就创建的 而是在模板调用时才创建 class Person1 { public: void showPerson1() { cout << "调用showPerson1" << endl; } }; class Person2 { public: void showPerson2() { cout << "调用showPerson2" << endl; } }; template class MyClass { public: T obj; public: void func1() { obj.showPerson1(); } void func2() { obj.showPerson2(); } }; void _03Test01() { MyClass myClass; myClass.func1(); //myClass.func2();//编译报错 说明函数调用时才会去创建成员函数 } void main() { _03Test01(); }
04 类模板对象做函数参数
//1、指定传入类型
//2、参数模板化
//3、整个类模板化 使用比较广泛
#includeusing namespace std; #include //类模板对象做函数参数 template class _04Person { public: T1 m_Name; T2 m_Age; _04Person(T1 name, T2 age) { this->m_Name = name; this->m_Age = age; } void showPerson() { cout << "name:" << this->m_Name << " age:" << this->m_Age << endl; } }; //1、指定传入类型 void PrintPerson1(_04Person & p) { p.showPerson(); } void _04Test01() { _04Person p("Tom", 19); PrintPerson1(p); } //2、参数模板化 template void PrintPerson2(_04Person & p) { cout << "T1类型:" << typeid(T1).name() << endl; cout << " T2类型:" << typeid(T2).name() << endl; p.showPerson(); } void _04Test02() { _04Person p("Tony", 29); PrintPerson2(p); } //3、整个类模板化 使用比较广泛' template void PrintPerson3(T& p) { cout << "T的类型为:" << typeid(T).name() << endl; p.showPerson(); } void _04Test03() { _04Person p("Jack", 39); PrintPerson3(p); } void main() { _04Test01(); _04Test02(); _04Test03(); }
05 类模板与继承
//当类模板碰到继承时,需要注意以下几点:
//1、当子类继承的父类为类模板时,子类在声明时,必须指定父类中T的类型
//2、如果不指定,编译器无法给子类分配内存
//3、如果想灵活指定出父类中T的类型,子类也需要变为类模板
#includeusing namespace std; //当类模板碰到继承时,需要注意以下几点: //1、当子类继承的父类为类模板时,子类在声明时,必须指定父类中T的类型 //2、如果不指定,编译器无法给子类分配内存 //3、如果想灵活指定出父类中T的类型,子类也需要变为类模板 //类模板与继承 template class Base { public: T m_Member; }; //如果不指定,编译器无法给子类分配内存 //class Son1:Base//报错 没有指明父类中T的数据类型 class Son1 :Base { }; //如果想灵活指定出父类中T的类型,子类也需要变为类模板 template class Son2 :Base { public: T2 m_Member2; Son2() { cout << "T1的类型为:" << typeid(T1).name() << endl; cout << "T2的类型为:" << typeid(T2).name() << endl; } }; void _05Test01() { Son2 s; } void main() { _05Test01(); }
06 类模板成员函数类外实现
#includeusing namespace std; //类模板成员函数类外实现 template class Student { public: T1 m_Name; T2 m_Age; Student(T1 name, T2 age); void showStudent(); }; template Student ::Student(T1 name, T2 age) { this->m_Name = name; this->m_Age = age; } template void Student ::showStudent() { cout << "姓名;" << this->m_Name << " 年龄:" << this->m_Age << endl; } void _06Test01() { Student s1("Tom", 19); s1.showStudent(); } void main() { _06Test01(); }
07 类模板分文件编写
//类模板份文件编写问题和解决方法
//问题:
//类模板中成员函数创建时机是在调用阶段,导致分文件编写时链接不到
//解决方法:
//方式1:直接包含.cpp源文件
//方式2:将声名和实现写到同一个文件中,并更改后缀名为.hpp,hpp是约定的名称,并不是强制
hpp文件:
#pragma once #includeusing namespace std; template class _07Person { public: T1 m_Name; T2 m_Age; _07Person(T1 name, T2 age); void showPerson(); }; template _07Person ::_07Person(T1 name, T2 age) { this->m_Name = name; this->m_Age = age; } template void _07Person ::showPerson() { cout << "name:" << this->m_Name << " age:" << this->m_Age << endl; }
#includeusing namespace std; //类模板份文件编写问题和解决方法 //问题: //类模板中成员函数创建时机是在调用阶段,导致分文件编写时链接不到 //解决方法: //方式1:直接包含.cpp源文件 //#include"person.cpp" //方式2:将声名和实现写到同一个文件中,并更改后缀名为.hpp,hpp是约定的名称,并不是强制 #include"person.hpp" void _07Test01() { _07Person p("Tom", 18); p.showPerson(); } void main() { _07Test01(); }
08 类模板与友元
#includeusing namespace std; //在编写友元函数实现之前还要提前声明类模板 template class _08Person; //友元函数类外实现需要在类之前编写实现 template void showPerson2(_08Person p) { cout << "name: " << p.m_Name << " age:" << p.m_Age << endl; } template class _08Person { //友元函数类内实现 friend void showPerson1(_08Person p) { cout << "name: " << p.m_Name << " age:" << p.m_Age << endl; } //友元函数类外实现 还需要加空模板参数列表 //如果全局函数是类外实现,还需要让编译器提前知道这个函数的存在 friend void showPerson2<>(_08Person p); public: T1 m_Name; T2 m_Age; _08Person(T1 name, T2 age) { this->m_Name = name; this->m_Age = age; } }; void _08Test01() { _08Person p("Jerry", 19); showPerson1(p); } void _08Test02() { _08Person p("Jack", 20); showPerson2(p); } void main() { //_08Test01(); _08Test02(); }
09 类模板案例-通用数组类封装
MyArray.hpp文件:
//自己的通用的数组类 #pragma once #include#include "MyArray.hpp" using namespace std; template void PrintArray(MyArray & arr) { for (int i = 0; i < arr.getSize(); i++) { cout << arr[i] << endl; } } void _09Test01() { MyArray arr1(5); for (int i = 0; i < 5; i++) { arr1.Push_Back(i); } cout << "arr1的打印输出:" << endl; PrintArray(arr1); } void _09Test02() { MyArray arr(10); arr.Push_Back("小一"); arr.Push_Back("小二"); arr.Push_Back("小三"); arr.Push_Back("小四"); arr.Push_Back("小五"); PrintArray(arr); cout << "容量" << arr.getCapacity() << endl; cout << "数量" << arr.getSize() << endl; } void main() { _09Test01(); _09Test02(); }
测试文件:
//自己的通用的数组类 #pragma once #include#include "MyArray.hpp" using namespace std; template void PrintArray(MyArray & arr) { for (int i = 0; i < arr.getSize(); i++) { cout << arr[i] << endl; } } void _09Test01() { MyArray arr1(5); for (int i = 0; i < 5; i++) { arr1.Push_Back(i); } cout << "arr1的打印输出:" << endl; PrintArray(arr1); } void _09Test02() { MyArray arr(10); arr.Push_Back("小一"); arr.Push_Back("小二"); arr.Push_Back("小三"); arr.Push_Back("小四"); arr.Push_Back("小五"); PrintArray(arr); cout << "容量" << arr.getCapacity() << endl; cout << "数量" << arr.getSize() << endl; } void main() { _09Test01(); _09Test02(); }



