一,概述
c++中类模板其实与函数模板类似,建立一个通用的类,如果希望成员变量的类型是任意的,用类模板实现。
类模板不是一个实际的类型,是虚拟的,和ppt模板一样,实例化的时候才会构建类。
二,类模板的定义
在定义模板时我们常用class, 但是你也可以为了区分类模板与函数模板运用typename。
template<class 类型名1,typename 类型名2 ,...>//clss与typename的作用是相同的
class 类名
{
模板中定义的类型名1 变量1;
模板中定义的类型名2 变量2;
}
类模板的实现注意类模板不可以自行类型推导,须显式指定类型,所以我们需要加<>。
并且 类模板在定义template时候,可以加上默认参数。
template<class T1,class T2=string>
类名<类型> 变量名(参数)
三,类模板对象当做函数的参数
类模板对象当做参数有三种传参方式
1,直接传入模板对象
void fun(person<string, int>& per)
2.类模板传入方式
template <class T1,class T2>
void fun3(person<T1,T2>& per)
3.整个类模板化
template <class T>
void fun4(T& per)
这里要注意传参的时候要传入类的引用,并且除了整个类的模板化不需要显式指定类型外,其他两个都需要。
四,类模板的继承
类模板的继承分为两种:普通类继承类模板,类模板继承类模板,
1.普通类继承类模板:普通类继承模板时,继承的模板类必须确定类型,否则无法通过编译。因为普通类编译时需要确定基类的类型,而基类却无法确定,所以必定报错。
class 子类:public 父类<指定类型>
实例;
#include <iostream>
using namespace std;
template<class T>
class father
{
public:
T m_age;
T m_name;
father(T m_age,T m_name):m_age(m_age),m_name(m_name){}
~father(){}
};
class son:public father<int>//father后一定要跟上一个指定类型
{
int age;
int name;
};
2.类模板继承类模板:类模板继承类模板不像普通类继承类模板那样,不需要写确定的类型,所以类模板继承要比普遍继承使用更加方便,因为类模板继承后仍是类模板,所以只需要写上T类型的即可,以便在被调用时通过子类模板确定基类模板。
实例:
#include <iostream>
using namespace std;
template<class T>
class father
{
public:
T m_age;
T m_name;
father(T m_age,T m_name):m_age(m_age),m_name(m_name){}
~father(){}
};
template<class T>
class son:public father<T>
{
int age;
int name;
};
五,类模板成员函数类外实现
在类模板中,函数的声明和定义都应该在h文件或者在mian的cpp中,在类中声明,在类外定义需要加上模板的类限定符。
template <class T1,class T2>
class myson :public person<T1, T2>
{
public:int display(T1 x);
};
template <class T1,class T2>
int myson<T1, T2>::display(T1 x){}
}
分文件编译时函数类外实现注意的问题: 类模板中成员函数的创建时机是在调用阶段,导致分文件编译时连接不到。
解决办法1:直接包含.cpp文件(一般不常使用)
解决办法2:将声明和实现写到同一个文件中,并且更改后缀名为.hpp文件, .hpp并不是强制这么写,至少一种约定俗成的名称。
实例:
在.hpp文件中-------------------------------------------------------------------
#include <iostream>
#include <cstring>
using namespace std;
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_aname=name;
this->m_aage=age;
}
template<class T1,class T2>
void person<T1,T2>::showperson()
{
cout<<this->m_name<<" "<<this->m_name<<endl;
}
void test1()
{
person<string,int>p("danny",18);
p.showperson();
}
在.cpp文件中-----------------------------------------------------------------------------
#include <iostream>
#include <cstring>
using namespace std;
#include<文件名.hpp>
void test1()
{
person<string,int>p("danny",18);
p.showperson();
}
int main(int argc, char *argv[])
{
test1();
cout << "Hello World!" << endl;
return 0;
}