模板引入的类型抽象是泛型程序设计的基础,具体为函数模板和类模板。
函数模板
语法:
template<typename T,typename S>
//每个模板类型形参前面必须带上关键字 class 或 typename
void my_swap(T &a,S b){
T temp = a;
a = b;
b = temp;
}
函数模板调用
int a = 20;
int b = 10;
char c = 97;
char d = 98;
my_swap(a,b);//自动匹配,类型必须完全一致
my_swap(a,d);//不可以,由于 int &p = c 不允许。
my_swap<int,char>(a,b);//显示调用模板函数。
练习
实现排序的模板函数(包括整形数,字符型和类类型)
参考代码如下:
//模板函数部分:
template<typename T>
int bubble_Sort(T *arr,int len){
if(NULL == arr){
throw invalid_argument("指针为空");
}
for(int i = 0;i<len;i++){
for(int j = 0;j<len-i-1;j++){
if(arr[j]<arr[j+1]){
T t;
t = arr[j];
arr[j] = arr[j+1];
arr[j+1] = t;
}
}
}
}
template<typename T>
void print_arr(T *arr,int len){
if(NULL == arr){
throw invalid_argument("指针为空");
}
for(int i=0;i<len;i++){
cout<<arr[i]<<endl;
}
}
//类类型
class Person{
public:
Person(string name = "zhangsan",int age = 23):m_name(name),m_age(age)
{
}
void setMsg(string name ,int age ){
this->m_name = name;
this->m_age = age;
}
//是否需要其他函数。
//重载<
bool operator <(Person &p){
if(this->m_age<p.m_age){
return false;
}
return true;
}
//重载=
Person& operator=(Person &p){
this->m_age = p.m_age;
this->m_name = p.m_name;
}
friend ostream& operator <<(ostream& out,Person &p){
out<<p.m_name<<endl<<p.m_age<<endl;
return out;
}
private:
string m_name;
int m_age;
};
//main函数测试代码
int arr[]={10,23,2,45};
int size_int = sizeof(arr)/sizeof(int);
int *p = NULL;
try{
bubble_Sort<int>(arr,size_int);
}
catch(exception &e){
cout<<e.what()<<endl;
}
try{
print_arr<int>(arr,size_int);
}
catch(exception &e){
cout<<e.what()<<endl;
}
//1、
Person *p = new Person[3];//调用5次无参构造函数
p[0].setMsg("test",20);
p[1].setMsg("test1",10);
p[2].setMsg("test2",40);
//2、
Person array[] = {{"test",20},{"test1",10},{"test2",40}};
//3、
Person p1("test",20);
Person p2("test1",10);
Person a[]={p1,p2};
cout<<"********************"<<endl;
try{
bubble_Sort<Person>(p,3);
}
catch(exception &e){
cout<<e.what()<<endl;
}
try{
print_arr<Person>(p,3);
}
catch(exception &e){
cout<<e.what()<<endl;
}
模板类
1、定义:
template<typename TYPENAME,typename TYPEAGE>
class Student{
public:
Student(){}
Student(TYPENAME name ,TYPEAGE age)
:m_name(name),m_age(age)
{
}
void showMsg(){
cout<<this->m_name<<this->m_age<<endl;
}
private:
TYPENAME m_name;
TYPEAGE m_age;
};
2、模板类对象的传参方式
//方式1
template<typename T,typename S>
void dowork(Student<T,S>&p)
{
p.showMsg();
}
//方式2
template<typename T>
void dowork(T &p)
{
p.showMsg();
}
//方式3
void dowork(Student<string,int>&p)
{
p.showMsg();
}
3、模板类派生类(派生模板类)
class stu:public Student<string,int>{//父类必须指定具体的类型
private:
string m_sex;
};
//派生模板类
template<typename T,typename S>
class stu:public Student<T,S>{
public:
stu(T name ,S age,T sex):Student<T,S>(name,age),m_sex(sex){}
private:
T m_sex;
};
4、模板类中的static变量
Student<string,int>p("zhangsan",52
dowork(p);
------- >static int a = 30
Student<string,int>p1("wang",42);
p1.showMsg();
------- >static int a = 30
Student<string,char>p2("wang",42);
p2.showMsg();
------- >static int a = 10
//p和p1不属于同一个类族。
5、模板类的多文件实现
template<typename TYPENAME,typename TYPEAGE>
class Animal{
public:
Animal(TYPENAME name ,TYPEAGE age );
void setMsg(TYPENAME name ,TYPEAGE age );
bool operator <(Animal &p);
Animal<TYPENAME,TYPEAGE>& operator=(Animal &p);
void show(){
cout<<this->m_name<<endl<<this->m_age;
}
template<typename T1,typename T2>
friend void display(Animal<T1,T2> &p, T1 name);
// friend ostream& operator <<(ostream& out,Animal &p);
private:
TYPENAME m_name;
TYPEAGE m_age;
};
#include "header1.h"
template<typename TYPENAME,typename TYPEAGE>
void display(Animal<TYPENAME,TYPEAGE> &p,TYPENAME name){
p.m_name = name;
}
template<typename TYPENAME,typename TYPEAGE>
Animal<TYPENAME,TYPEAGE>::Animal(
TYPENAME name = "zhangsan",TYPEAGE age = 23)
:m_name(name),m_age(age)
{
}
template<typename TYPENAME,typename TYPEAGE>
void Animal<TYPENAME,TYPEAGE>::setMsg(TYPENAME name ,TYPEAGE age){
this->m_name = name;
this->m_age = age;
}
template<typename TYPENAME,typename TYPEAGE>
bool Animal<TYPENAME,TYPEAGE>::operator <(Animal &p){
if(this->m_age<p.m_age){
return false;
}
return true;
}
template<typename TYPENAME,typename TYPEAGE>
Animal<TYPENAME,TYPEAGE>& Animal<TYPENAME,TYPEAGE>::operator=(Animal &p){
this->m_age = p.m_age;
this->m_name = p.m_name;
}
实现数组模板类
能够管理整形,字符型和student类类型的数据。
完成运算符重载 [] << =等
要求:模板类分文件实现。