C++模板
模板概念:泛型编程,将类型参数化,在编译阶段不指定参数类型,运行阶段动态获取参数的技术,C++中分为函数模板和类模板
语法:
template<typename T>
template -- 声明创建模板
typename -- 表明其后面的符号是一种数据类型,可以用class代替
T -- 通用的数据类型,名称可以替换,通常为大写字母
类模板:
类模板的语法和使用:
类模板:建立一个通用的类,类中的成员的数据类型可以不具体制定,用一个虚拟的类来代表
template<class T,class A>
class Person{
Person(T name,A age){
this->m_Name=name;
this->m_Age=age;
}
public:
T m_Name;
A m_Age;
}
类模板的使用方法:
//类模板的使用
Person<string,int> p1("孙悟空",500);
类模板和函数模板的区别:
- 类模板没有自动类型推导的使用方式,类模板使用只能用显示指定类型的方式
- 类模板在模板参数列表中可以有默认参数
类模板中成员函数创建时机:
- 普通类中的成员函数在程序允许时就创建
- 类模板中的成员函数在调用时才创建
类模板对象做函数参数:
类模板实例化对象,向函数传参的三种方式:
- 指定传入的类型, ----直接显示对象的数据类型
- 参数模板化 ----将对象中的参数变为模板进行传递
- 整个类模板化 ----将这个对象类型模板化进行传递
创建一个Person类模板:
template<class T1,class T2>
class Person{
public:
Person(T1 name,T2 age){
this->m_Name=name;
this->m_Age=age;
}
void showPerson(){
cout<<"姓名:" <<this->m_Name <<" 年龄:"<<this->m_Age<<endl;
}
T1 m_Name;
T2 m_Age;
}
//1、指定传入的类型, ----直接显示对象的数据类型
void printPerson1(Person<string,int> &p){
p.showPerson();
}
//2、参数模板化 ----将对象中的参数变为模板进行传递
template<class T1,class T2>
void printPerson1(Person<T1,T2> &p){
p.showPerson();
}
//3、整个类模板化 ----将这个对象类型模板化进行传递
template<class T>
void printPerson1(T &p){
p.showPerson();
}
void test(){
Person<string,int> p1("张三",12);
printPerson1(p1);
Person<string,int> p2("李四",13);
printPerson1(p2);
Person<string,int> p3("王五",14);
printPerson1(p3);
}
类模板与继承:
- 子类继承父类类模板是,子类在声明时要指出父类中T的类型
- 不指定,编译器无法给分配内存空间
- 如果向灵活指定父类中T的类型,子类需要变为类模板
#include <iostream>
using namespace std;
//类模板与继承
template<class T1, class T2>
class Person5
{
public:
Person5() {}
Person5(T1 name, T2 age)
{
this->m_Name = name;
this->m_Age = age;
}
void showPerson() {
cout << "姓名:" << this->m_Name << "年龄:" << this->m_Age << endl;
}
T1 m_Name;
T2 m_Age;
~Person5(){}
};
//1、子类继承父类类模板是,子类在声明时要指出父类中T的类型
class Son:public Person5<string,int>
{
public:
Son(string name,int age)
{
this->Person5::m_Name = name;
this->Person5::m_Age = age;
this->a = 10;
}
int a;
};
//2、如果向灵活指定父类中T的类型,子类需要变为类模板
template<class T1,class T2>
class Son2 :public Person5<T1,T2>
{
};
int main() {
Person5<string,int> s1=Son("TOM",12);
cout << "T的类型" << typeid(s1).name() << endl;
//s1.showPerson();
Son2<string, int> s2();
cout << "T的类型" << typeid(s2).name() << endl;
//s2.showPerson();
return 0;
}
类模板的分文件编写:
C++编程时会拆分文件,头文件里声明,源文件做具体实现,类模板的成员函数创建时机是在的调用阶段,导致分文件编写时链接不到
解决:
- 1、直接包含.cpp源文件
- 在使用的地方,不是导入头文件,直接源文件
- 2、将声明和实现写到同一个文件中,并更改后缀名为.hpp,.hpp是约定的名称,表明这是一个类模板