一、 类模板对象当做函数的参数
格式:
//第一种方式,直接传入模板对象
void fun(person<string, int>& per)
案例:
#include<iostream>
using namespace std;
#include<string>
//类模板
template<class NameType,class AgeType>
class Person {
public:
Person(NameType name,AgeType age) {
this->m_age=age;
this->m_name=name;
}
void showPerson() {
cout<<"姓名:"<<this->m_name<<"年龄:"<<this->m_age<<endl;
}
public:
NameType m_name;
AgeType m_age;
};
//1.指定传入的类型
void printPerson(Person<string,int> &p)
{
p.showPerson();
}
void test01()
{
Person<string,int>p("strangeDoc",100);
printPerson(p);
}
int main()
{
test01();
system("pause");
return 0;
}
//第二种方式,类模板传入方式
格式:
template <class T1,class T2>
void fun3(person<T1,T2>& per)
案例:
#include<iostream>
using namespace std;
#include<string>
#include<typeinfo>
//类模板
template<class NameType,class AgeType>
class Person {
public:
Person(NameType name,AgeType age) {
this->m_age=age;
this->m_name=name;
}
void showPerson() {
cout<<"姓名:"<<this->m_name<<"年龄:"<<this->m_age<<endl;
}
public:
NameType m_name;
AgeType m_age;
};
//2.参数模板化
template<class T1,class T2>
void printPerson02(Person<T1,T2> &p)
{
p.showPerson();
//cout<<"T1的类型为:"<<typeid(T1).name()<<endl;
//cout<<"T2的类型为:"<<typeid(T2).name()<<endl;
}
void test02()
{
Person<string,int>p("capitain",90);
printPerson02(p);
}
int main()
{
test02();
system("pause");
return 0;
}
//第三种方式,整个类模板化
格式:
template <class T>
void fun4(T& per)
案例:
#include<iostream>
using namespace std;
#include<string>
#include<typeinfo>
//类模板
template<class NameType,class AgeType>
class Person {
public:
Person(NameType name,AgeType age) {
this->m_age=age;
this->m_name=name;
}
void showPerson() {
cout<<"姓名:"<<this->m_name<<"年龄:"<<this->m_age<<endl;
}
public:
NameType m_name;
AgeType m_age;
};
//3.整个类模板化
template<typename T1>
void printPerson3(T1 &p)
{
p.showPerson();
}
void test03()
{
Person<string,int>p("ironMan",30);
printPerson3(p);
}
int main()
{
test03();
system("pause");
return 0;
}
二、类模板继承
模板类的继承包括四种:
1.(普通类继承模板类)
1 template<class T>
2 class TBase{
3 T data;
4 ……
5 };
6 class Derived:public TBase<int>{
7 ……
8 };
2.(模板类继承了普通类(非常常见))
1 class TBase{
2 ……
3 };
4 template<class T>
5 class TDerived:public TBase{
6 T data;
7 ……
8 };
3.(类模板继承类模板)
1 template<class T>
2 class TBase{
3 T data1;
4 ……
5 };
6 template<class T1,class T2>
7 class TDerived:public TBase<T1>{
8 T2 data2;
9 ……
10 };
4.(模板类继承类模板,即继承模板参数给出的基类)
1 #include<iostream>
2 using namespace std;
3
4 class BaseA{
5 public:
6 BaseA(){cout<<"BaseA founed"<<endl;}
7 };
8 class BaseB{
9 public:
10 BaseB(){cout<<"BaseB founed"<<endl;}
11 };
12 template<typename T, int rows>
13 class BaseC{
14 private:
15 T data;
16 public:
17 BaseC():data(rows){
18 cout<<"BaseC founed "<< data << endl;}
19 };
20 template<class T>
21 class Derived:public T{
22 public:
23 Derived():T(){cout<<"Derived founed"<<endl;}
24 };
25
26 void main()
27 {
28 Derived<BaseA> x;// BaseA作为基类
29 Derived<BaseB> y;// BaseB作为基类
30 Derived<BaseC<int, 3> > z; // BaseC<int,3>作为基类
31 }
三、类模板成员函数类外实现
在类模板中,函数的声明和定义都应该在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){}
}
小秘密:一般情况下会把定义模板类的文件后缀修改成.hpp的形式。
练习:实现一个通用的数组类 ( )
第一点:他需要支持基本数据类型和自定义类型。t* parr,int size,int cap) cap是容量,已经存了多少元素。如果存了6个则cap=6
第二点:通用数组中的数据要放入堆内存(new),需要提供
第三点:需要实现构造 析构 有参构造函数
第四点:需要实现==运算符重载,下标运算符[]重载。
第五点:提供两个函数,可以给数组进行为插和尾删除。
案例:
#include <iostream>
#include <string>
using namespace std;
//类模板中成员函数类外实现
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;
}
void test01()
{
Person<string, int> p("Jerry", 20);
p.showPerson();
}
int main() {
test01();
system("pause");
return 0;
}
四、 类模板的友元函数
1.类外实现友元函数:
先需要在类内声明函数,声明的时候需要加空模板列表,也就是函数名后<>
其次需要在类外实现,但一定是类的定义前实现,在friend函数声明前需要有函数体。
最后在定义完友元函数后,需要先声明模板类。
2.类内实现模板类的友元函数,和普通友元函数实现一样。
案例:
/* program2 */
#include <iostream>
using std::cout;
using std::endl;
//template prototypes
template <typename T> void counts();
template <typename T> void report(T &);
//template class
template <typename TT>
class HasFriendTem
{
private:
TT item;
static int cnts;
public:
HasFriendTem(const TT & i):item(i){cnts++;}
~HasFriendTem(){cnts--;}
friend void counts<TT>();
friend void report<>(HasFriendTem<TT> &);
};
template <typename TT>
int HasFriendTem<TT>::cnts=0;
//template friend functions definitions
template <typename T>
void counts()
{
cout<<"template size:"<<sizeof(HasFriendTem<T>)<<";";
cout<<"template counts():"<<HasFriendTem<T>::cnts<<endl;
}
template <typename T>
void report(T& hf)
{
cout<<hf.item<<endl;
}
int main()
{
counts<int>();
HasFriendTem<int> hfi1(10);
HasFriendTem<int> hfi2(20);
HasFriendTem<double> hfdb(15.5);
report(hfi1);//generate report(HasFriendTem<int> &)
report(hfi2);
report(hfdb);//generate report(HasFriendTem<double> &)
cout<<"counts<int>() output:\n";
counts<int>();
cout<<"counts<double() output:\n";
counts<double>();
return 0;
}