类模板
1 类模板语法
类模板作用:
- 建立一个通用类,类中的成员 数据类型可以不具体制定,用一个虚拟的类型来代表。
语法:
解释:
template — 声明创建模板
typename — 表面其后面的符号是一种数据类型,可以用class代替
T — 通用的数据类型,名称可以替换,通常为大写字母
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 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 test01(){ Person<string,int>p1("Tom", 10); p1.showPerson(); }
|
2 类模板和函数模板的区别
类模板与函数模板区别主要有两点:
- 类模板没有自动类型推导的使用方式
- 类模板在模板参数列表中可以有默认参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
template<class Nametype,class agetype = int> 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 test01(){ Person<string,int>p1("Tom", 10); Person <string> p("猪八戒", 999); }
|
3 类模板中成员函数创建时机
类模板中成员函数和普通类中成员函数创建时机是有区别的:
- 普通类中的成员函数一开始就可以创建
- 类模板中的成员函数在调用时才创建
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| #include<iostream> using namespace std; class Person1 { public: void showPerson1() { cout << "Person1 show" << endl; } };
class Person2 { public: void showPerson2() { cout << "Person2 show" << endl; } };
template<class T> class myclass{ public: T obj; void func1(){ obj.showPerson1(); } void func2(){ obj.showPerson2(); } }; int main() { myclass<Person1>m; m.func1(); return 0; }
|
4 类模板对象做函数参数
- 类模板实例化出的对象,向函数传参的方式一共有三种:
- 指定传入的类型:直接显示对象的数据类型
- 参数模板化: 将对象中的参数变为模板进行传递
- 整个类模板化:将这个对象类型模板化进行传递
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| #include<iostream> #include<typeinfo> using namespace std; template<class T1,class T2> class Person{ public: Person(T1 name,T2 age){ m_name = name; m_age = age; } void showPerson() { cout << "name: " << this->m_name << " age: " << this->m_age << endl; } T1 m_name; T2 m_age; };
void printPerson1(Person<string,int>&p){ p.showPerson(); } void test01(){ Person<string,int>P("hxx",20); printPerson1(P); }
template<class T1,class T2> void printPerson2(Person<T1,T2>&p){ p.showPerson(); cout<<"T1的类型是:"<<typeid(T1).name()<<endl; cout<<"T2的类型是:"<<typeid(T2).name()<<endl; } void test02(){ Person<string,int>P("qzy",20); printPerson2(P); }
template<class T> void printPerson3(T &p){ p.showPerson(); cout<<"T的类型是:"<<typeid(T).name()<<endl; } void test03(){ Person<string,int>P("hq",20); printPerson3(P); } int main(){ test01(); test02(); test03(); return 0; }
|
5 类模板成员函数类外实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| template<class T1,class T2> class Person{ public: Person(T1 name,T2 age); void showPerson(); T1 m_name; T2 m_age; };
template<class T1,class T2> Person<T1,T2>::Person(T1 name,T2 age){ this->m_age = age; this->m_name = name; } template<class T1,class T2> void Person<T1,T2>::showPerson(){ cout << "name: " << this->m_name << " age: " << this->m_age << endl; } void test01(){ Person<string,int>P("hxx",20); P.showPerson(); }
|
6 类模板分文件编写
问题:
- 类模板中成员函数创建时机是在调用阶段,导致分文件编写时链接不到
解决:
- 解决方式1:直接包含.cpp源文件
- 解决方式2:将声明和实现写到同一个文件中,并更改后缀名为.hpp,hpp是约定的名称,并不是强制
示例:
person.hpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| #pragma once #include <iostream> using namespace std; #include <string>
template<class T1, class T2> class Person { public: Person(T1 name, T2 age); void showPerson(); public: T1 m_Name; T2 m_Age; };
template<class T1, class T2> Person<T1, T2>::Person(T1 name, T2 age) { this->m_Name = name; this->m_Age = age; }
template<class T1, class T2> void Person<T1, T2>::showPerson() { cout << "姓名: " << this->m_Name << " 年龄:" << this->m_Age << endl; }
|
.cpp文件
1 2 3 4 5 6 7 8 9 10 11 12 13
| #include<iostream> using namespace std; #include "person.hpp" void test01() { Person<string, int> p("Tom", 10); p.showPerson(); }
int main() { test01(); return 0; }
|
7 类模板与友元
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| #include<iostream> using namespace std;
template<class T1, class T2> class Person;
template<class T1, class T2> void printPerson2(Person<T1,T2>&p){ cout << "姓名: " << p.m_Name << " 年龄:" << p.m_Age << endl; }
template<class T1, class T2> class Person { public: friend void printPerson(Person<T1,T2>p){ cout << "姓名: " << p.m_Name << " 年龄:" << p.m_Age << endl; } friend void printPerson2<>(Person<T1,T2>&p); Person(T1 name, T2 age){ this->m_Name = name; this->m_Age = age; } private: T1 m_Name; T2 m_Age; };
void test01(){ Person<string,int>p("hxx",20); printPerson(p); printPerson2(p); } int main(){ test01(); return 0; }
|