1、类模板定义
#include<iostream>
#include<cmath>
#include<cstring>
#include<stdio.h>
#include<stdlib.h>
#include<vector>
using namespace std;
template<typename NameType,typename AgeType> //声明一个模板,告诉编译器后面代码中紧跟着的T不要报错,T是一个通用数据类型
class Person
{
public:
Person(NameType name,AgeType age)
{
this->name=name;
this->age=age;
}
void showPerson()
{
cout<<name<<" "<<age<<endl;
}
NameType name;
AgeType age;
};
int main()
{
Person<string,int> p1("孙悟空",999);
p1.showPerson();
return 0;
}
2、类模板和函数模板区别:
- 类模板没有自动类型推导的使用方式
- 类模板在模板参数列表中可以有默认参数
#include<iostream>
#include<cmath>
#include<cstring>
#include<stdio.h>
#include<stdlib.h>
#include<vector>
using namespace std;
template<typename NameType,typename AgeType=char> //声明一个模板,告诉编译器后面代码中紧跟着的T不要报错,T是一个通用数据类型
class Person
{
public:
Person(NameType name,AgeType age)
{
this->name=name;
this->age=age;
}
void showPerson()
{
cout<<name<<" "<<age<<endl;
}
NameType name;
AgeType age;
};
int main()
{
Person<string,int> p1("孙悟空",99);
Person<string> p2("孙悟空",99);
p1.showPerson();
p2.showPerson();
return 0;
}
3、类模板中成员函数调用时机
类模板中成员函数在调用时才去创建
#include<iostream>
#include<cmath>
#include<cstring>
#include<stdio.h>
#include<stdlib.h>
#include<vector>
using namespace std;
class Person1
{
public:
void showPerson1()
{
cout<<"Person1:show"<<endl;
}
};
class Person2
{
public:
void showPerson2()
{
cout<<"Person2:show"<<endl;
}
};
template<typename T>
class MyClass
{
public:
T obj;
void func1()
{
obj.showPerson1();
}
void func2()
{
obj.showPerson2();
}
};
int main()
{
MyClass<Person1>p1;
p1.func1();
MyClass<Person2>p2;
p2.func2();
return 0;
}
4、类模板对象做函数参数
- 指定传入类型
- 参数模板化
- 整个类模板化
#include<iostream>
#include<cmath>
#include<cstring>
#include<stdio.h>
#include<stdlib.h>
#include<vector>
#include<typeinfo>
using namespace std;
template<typename NameType,typename AgeType> //声明一个模板,告诉编译器后面代码中紧跟着的T不要报错,T是一个通用数据类型
class Person
{
public:
Person(NameType name,AgeType age)
{
this->name=name;
this->age=age;
}
void showPerson()
{
cout<<name<<" "<<age<<endl;
}
NameType name;
AgeType age;
};
//指定传入类型
void printfPerson1(Person<string,int> &p)
{
p.showPerson();
}
//参数模板化
template<typename NameType,typename AgeType>
void printfPerson2(Person<NameType,AgeType> &p)
{
p.showPerson();
cout<<"NameType的类型为:"<<typeid(NameType).name()<<endl;
cout<<"AgeType的类型为:"<<typeid(AgeType).name()<<endl;
}
//整个类模板化
template<typename T>
void printfPerson3(T &p)
{
p.showPerson();
cout<<"T的类型为:"<<typeid(T).name()<<endl;
}
int main()
{
Person<string,int> p1("孙悟空",999);
printfPerson1(p1);
Person<string,int> p2("猪八戒",99);
printfPerson2(p2);
Person<string,int> p3("唐僧",20);
printfPerson3(p3);
return 0;
}
5、类模板的继承
如果父类时类模板,子类需要明确模板数据类型或者也写成类模板
#include<iostream>
#include<cmath>
#include<cstring>
#include<stdio.h>
#include<stdlib.h>
#include<vector>
#include<typeinfo>
using namespace std;
template<typename T> //声明一个模板,告诉编译器后面代码中紧跟着的T不要报错,T是一个通用数据类型
class Base
{
public:
T m;
};
class Son:public Base<int>
{
};
template<typename T1,typename T2>
class Son2:public Base<T2>
{
T1 obj;
};
int main()
{
Son s1;
Son2<string,int> s2;
return 0;
}
6、类模板成员函数类外实现
#include<iostream>
#include<cmath>
#include<cstring>
#include<stdio.h>
#include<stdlib.h>
#include<vector>
using namespace std;
template<typename NameType,typename AgeType> //声明一个模板,告诉编译器后面代码中紧跟着的T不要报错,T是一个通用数据类型
class Person
{
public:
Person(NameType name,AgeType age);
void showPerson();
NameType name;
AgeType age;
};
template<typename T1,typename T2>
Person<T1,T2>::Person(T1 name,T2 age)
{
this->name=name;
this->age=age;
}
template<typename T1,typename T2>
void Person<T1,T2>::showPerson()
{
cout<<name<<" "<<age<<endl;
}
int main()
{
Person<string,int> p1("孙悟空",999);
p1.showPerson();
return 0;
}
7、类模板分文件编写
不能#include"Person.h",因为类模板中成员函数在调用时才去创建,这就导致在链接阶段,编译器根本没看"Person.cpp"中成员函数的实现。
解决方法:
- 直接包含源文件 #include"Person.cpp"
- 将.h和.cpp中的内容写到一起,将后继名改为.hpp文件 #include"Person.hpp"
8、类模板与友元
- 全局函数类内实现:直接在类内声明友元即可
- 全局函数类外实现:需要提前让编译器知道全局函数的存在
#include<iostream>
#include<cmath>
#include<cstring>
#include<stdio.h>
#include<stdlib.h>
#include<vector>
using namespace std;
template<typename NameType,typename AgeType>
class Person;
template<typename NameType,typename AgeType>
void printPerson2(Person<NameType,AgeType> p)
{
cout<<p.name<<" "<<p.age<<endl;
}
template<typename NameType,typename AgeType> //声明一个模板,告诉编译器后面代码中紧跟着的T不要报错,T是一个通用数据类型
class Person
{
friend void printPerson(Person<NameType,AgeType> p)
{
cout<<p.name<<" "<<p.age<<endl;
}
friend void printPerson2<>(Person<NameType,AgeType> p);
public:
Person(NameType name,AgeType age);
NameType name;
AgeType age;
};
template<typename T1,typename T2>
Person<T1,T2>::Person(T1 name,T2 age)
{
this->name=name;
this->age=age;
}
int main()
{
Person<string,int> p1("孙悟空",999);
printPerson2(p1);
return 0;
}