模板
- 模板:
参数多态化的工具(根据指定参数类型动态处理) - GC:
所谓参数化的多态性,是指将程序所处理的对象的类型参数化,使一段程序代码可以用于处理不同类型的对象 - 作用:
采用模板编程,可以为各种逻辑功能相同而数据类型不同的程序提供一种代码共享的机制(模板用于表达逻辑结构相同,但具体数据元素类型不同的数据)
函数模板
- 函数模板:用虚拟数据类型代替。等到运行时才进行类型替换
为所有的函数提供唯一的一段函数代码,提高了函数设计的通用性 - 函数模板的使用:
使用函数模板的方法是先说明函数模板,然后实例化成相应的模板函数进行调用执行
函数模板不是函数,不能够被执行
置换代码中的类型函数,得到模板函数——实例化
实例化后的模板函数是真正的函数,可以被执行
使用函数模板时,可以进行隐性调用,但是不允许进行隐式类型转换
隐性调用和显性调用
template <typename T>
//隐式调用:由编译器自行推导数据类型
//隐式调用举例
#include "iostream"
using namespace std;
template <typename T>
T add(T a, T b)
{
return a + b;
}
int main()
{
int a = 1, b = 2;
float c = 1.9, d = 2.3;
cout << "int :" << add(a,b) << endl;
cout << "float:" << add(c,d) << endl;
return 0;
}
运行结果:
int :3
float:4.2
当传入的两个数据类型不一样,编译器不再能够判断需要得出的结果的时候,就要用到显式调用
//显式调用举例
#include "iostream"
using namespace std;
template <typename T>
T add(T a, T b)
{
return a + b;
}
int main()
{
int a = 1, b = 2;
float c = 1.9, d = 2.3;
cout << "int :" << add(a,b) << endl;
cout << "float:" << add(c,d) << endl;
cout << add<float>(a,c)<< endl;//显式调用举例,用尖括号对想要得到的数据类型进行定义
return 0;
}
运行结果:
int :3
float:4.2
2.9
类模板
-
类模板:类的数据类型可以和成员函数相同,但是不能和友元函数重名
-
类外定义的任何函数用到了类的模板都需要进行显式调用
-
对象在创建时一定要显式调用
-
将类定义中的数据类型参数化
-
类模板实际上是函数模板的推广,可以用相同类模板来组建任意类型的对象集合
-
使用:
类模板的实例化:用具体的数据类型替换模板的参数以得到具体的类(模板类)
模板类也可以实例化为对象
用下列方式创建类的实例:
类名<类型实参表>对象名称
缺省模板参数?
成员模板
为什么需要成员模板
实例化
隐式实例
显式实例
模板的全特化与偏特化
类模板举例:
#include "iostream"
using namespace std;
template <typename T>
class complex
{
public:
complex(T a, T b);
complex() {}
void print();
template <typename w>
friend complex<w> operator>>(istream &in, complex<w> &B);
template <typename q>
friend ostream& operator<<(ostream &out, const complex<q> &C);
template <typename t>
friend complex<t> operator+(const complex<t> &A, const complex<t> &B);
private:
T m_a;
T m_b;
};
template <typename T>
complex<T>::complex(T a, T b)
{
m_a = a;
m_b = b;
}
template <typename T>
void complex < T>::print()
{
cout << m_a << "+" << m_b << "i" << endl;
}
template <typename w>
complex<w> operator>>(istream &in, complex<w> &B)
{
w x, y;
scanf("%d%di", &x, &y);
getchar();
B.m_a = x;
B.m_b = y;
return B;
}
template <typename q>
ostream& operator<<(ostream& out, const complex<q> &C)
{
cout << C.m_a << "+" << C.m_b << "i" << endl;
}
template <typename t>
complex<t>operator+(const complex<t>& A, const complex <t>& B)
{
complex<t> C;
C.m_a = A.m_a + B.m_a;
C.m_b = A.m_b + B.m_b;
return C;
}
int main()
{
complex<int> c;
complex<int> c1(2, 3);
cin >> c;
cout << c << endl;
complex<int> c2;
c2 = c1 + c;
cout << c2 << endl;
complex<float> c3(1.1, 2.2);
complex<float> c4(2.3, 3.4);
complex<float> c5;
c5 = c3 + c4;
cout << c5 << endl;
return 0;
}
运行结果:
1 2
1+2i
3+5i
3.4+5.6i