目录
1.模板的概念
比如在制作ppt时,我们常用到ppt的模板,但一个ppt模板不能适用于所有的主题,要根据不同的情况来选择合适的模板。
2.类模板
1.类模板基本语法
#include<bits/stdc++.h>
using namespace std;
template<class nametype,class agetype>
class person
{
public:
person(nametype name,agetype age)
{
this -> name = name,this -> age = age;
}
void show()
{
cout << this -> name << ' ' << this -> age;
}
nametype name;
agetype age;
};
int main()
{
person<string,int> p1("xiaoming",18);
p1.show();
return 0;
}
2.类模板与函数模板区别
#include<bits/stdc++.h>
using namespace std;
template<class nametype,class agetype = int>//默认参数设置为int
class person
{
public:
person(nametype name,agetype age)
{
this -> name = name,this -> age = age;
}
void show()
{
cout << this -> name << ' ' << this -> age;
}
nametype name;
agetype age;
};
int main()
{
//上面将默认参数设置为int所以这里初始化p1时只写一个string即可
person<string> p1("xiaoming",18);
p1.show();
return 0;
}
3.类模板中成员函数创建时机
#include<bits/stdc++.h>
using namespace std;
class person1
{
public:
void show1()
{
cout << "person1" << endl;
}
};
class person2
{
public:
void show2()
{
cout << "person2" << endl;
}
};
template<class T>
class myclass
{
public:
T obj;
void func1()
{
obj.show1();
}
void func2()
{
obj.show2();
}
};
//编译器不知道obj是什么数据类型,所以类模板中的函数并不是一开始就创建的
//而是在模板调用时再生成
int main()
{
myclass<person1> c;
c.func1();
return 0;
}
4.类模板对象做函数参数
typeid().name()
用于显示一个变量的数据类型
#include<bits/stdc++.h>
using namespace std;
template<class T1,class T2>
class person
{
public:
T1 name;
T2 age;
person(T1 name,T2 age)
{
this -> name = name,this -> age = age;
}
void show()
{
cout << this -> name << ' ' << this -> age << endl;
}
};
//1、指定传入类型
void printperson1(person<string,int> &p)
{
p.show();
}
//2.参数模板化
template<class T1,class T2>
void printperson2(person<T1,T2> &p)
{
p.show();
cout << typeid(T1).name() << endl;
cout << typeid(T2).name() << endl;
}
//3.整个类模板化
template<class t>
void printperson3(t &p)
{
p.show();
cout << typeid(t).name() << endl;
}
int main()
{
person<string,int>p1("xiaoming",18);
printperson1(p1);
person<string,int>p2("xiaohong",19);
printperson2(p2);
printperson3(p2);
return 0;
}
5.类模板与继承
#include<bits/stdc++.h>
using namespace std;
template<class t>
class base
{
t a;
};
//类模板继承时必须要知道父类中的t的类型
class son1 : public base<int>
{};
//如果想灵活指定父类中的t类型,子类也需要变为类模板
template<class t1,class t2>
class son2 : public base<t2>
{
public:
t1 obj;
};
int main()
{
son2<char,int> s;
//此时t1会变为char类型,t2会变为int类型,并且父类的t也变为int类型
return 0;
}
6.类模板成员函数类外实现
#include<bits/stdc++.h>
using namespace std;
template<class T1,class T2>
class person
{
public:
T1 name;
T2 age;
//成员函数类内声明
person(T1 name,T2 age);
// {
// this -> name = name,this -> age = age;
// }
void show();
// {
// cout << this -> name << ' ' << this -> age << endl;
// }
};
//构造函数类外实现
//要提供作用域,告诉编译器T1,和T2是什么,告诉编译器这是一个类模板的类外函数实现
template<class T1,class T2>
person<T1,T2>::person(T1 name,T2 age)
{
this -> name = name,this -> age = age;
}
//成员函数类外实现
template<class T1,class T2>
void person<T1,T2>::show()
{
cout << this -> name << ' ' << this -> age << endl;
}
int main()
{
person<string,int>p1("xiaoming",18);
p1.show();
return 0;
}
7.类模板分文件编写
#pragma once
防止头文件重复包含
8.类模板与友元
#include<bits/stdc++.h>
using namespace std;
//让编译器提前知道存在一个名称为person的类模板
template<class T1,class T2>
class person;
template<class T1,class T2>
void printperson2(person<T1,T2> p)
{
cout << "类外实现" << ' ' << p.name << ' ' << p.age << endl;
}
template<class T1,class T2>
class person
{
private:
T1 name;
T2 age;
public:
//全局函数类内实现
//加上friend使得它可以访问到私有成员name和age
friend void printperson(person<T1,T2> p)
{
cout << "类内实现" << ' ' << p.name << ' ' << p.age << endl;
}
//全局函数类外实现
//加空模板参数列表
//如果全局函数是类外实现的话,需要让编译器提前知道函数的存在
friend void printperson2<>(person<T1,T2> p);
person(T1 name,T2 age)
{
this -> name = name,this -> age = age;
}
};
int main()
{
person<string,int>p1("xiaoming",18);
printperson(p1);
printperson2(p1);
return 0;
}