类模板的使用方法基本与函数模板一致
template<typename T>
class Person {
public:
Person(T ID,T Age) {
this->mID = ID;
this->mAge = Age;
}
friend void printMessage(Person p) {
cout << "the student's ID is " << p.mID << " & the age is " << p.mAge << endl;
}
private:
T mID;
T mAge;
};
但是在调用模板,实例化对象时,模板函数可以自动推导类型,类模板必须显式指定类型
int main() {
Person<int> p(130,120); //这里显式指定T为int类型
printMessage(p);
}
运行结果:
the student's ID is 130 & the age is 120
模板类派生普通类
模板类的派生方式与普通类并不相同
因为类区会定义对象,所以对象需要编译分配内存
所以需要提前指明派生类类型
class Student : public Person<int>{
//代码
}
//如上就将派生类类型定义为整数类型
模板类派生模板类
template<typename T>
class Teacher : public Person<T>{
//代码
}
类模板头文件和源文件分开编写
要注意与普通类的区别
#include"Person.h"
template<typename T> //首先需要写清标识符
Person<T>::Person(T age){ //这里也要带上参数
this->mAge=age;
}
template<typename T> //首先需要写清标识符
void Person<T>::Show(){ //这里也要带上参数
cout<<"Hello"<<endl;
}
易错点
在调用上述头文件与源文件分开编写的类模板时,编译器能够成功编译,但是不能正常运行,调用过程:
//头文件<Person.h>
#include<iostream>
using namespace std;
template<typename T>
class Person {
public:
Person(T ID) ;
void show;
T mID;
};
/*------------------------------------------*/
//源文件<Person.cpp>
#include""Person.h"
template<typename T>
Person::Person(T ID){
this->mID=ID;
}
template<typename T>
void Person::Show(){
cout<<"the ID is "<<mID<<endl;
}
/*------------------------------------------*/
//主文件<main.cpp>
#include<iostream>
#include<Person.h>
using namespace std;
int main(){
Person<int> p(1301);
p.show();
return 0;
}
错误原因和模板的实现机制以及C++的编译机制有关
在C++编译过程中,各个文件独立编译,如上,在主函数编译过程中,发现一个函数调用,但是在当前文件并没有实现,此时,就会在函数位置生成符号,等待后续文件编译完成
而在Person.cpp的函数模板内,只对函数模板进行了二次编译,却没有具体调用(始终是T类型,并没有实例化成int,float…等类型进行实际调用),模板实现机制是经过二次编译,然后通过调用生成具体函数
解决方法:
- 将主文件中#include<Person.h>修改为#include<Person.cpp>,相当于将整个文件拷贝进主文件,从而实现运行(或者通过内联函数)
- 一般情况下,习惯将.cpp文件修改为.hpp文件,然后引入主文件中即可
类模板与static成员
static修饰的变量,由相同实例化类型的对象所有,不归全体类模板实例对象所有:
#include<iostream>
using namespace std;
template<typename T>
class Num {
public:
static int a;
};
//类外初始化
template<typename T> int Num<T>::a = 0;
int main() {
Num<int> p1, p2, p3;
Num<char> p4, p5, p6;
p1.a = 10;
p4.a = 100;
cout << p1.a << " " << p2.a << " " << p3.a << endl;
cout << p4.a << " " << p5.a << " " << p6.a << endl;
return 0;
}
运行结果
10 10 10
100 100 100