函数模板就是将函数类型参数化,方便编程。
1、普通函数模板
#include<iostream>
using namespace std;
template <typename T>//template是告诉编译器,要开始泛型编程了,并用T替代函数的参数类型
void myswap(T& a, T& b)
{
T c;
c = a;
a = b;
b = c;
cout << "t" << endl;
}
template <typename T, typename T1>//定义两个泛型,其实定义一个也可以因为都是 int型,但数组是char型时就要两个了,这里举例说明定义多个泛型
void mysort(T* a, T1 len)//
{
T1 i = 0, j = 0, c;
for (i; i < len; ++i)
for (j = i + 1; j < len; ++j)
{
if (a[i] > a[j])
{
c = a[i];
a[i] = a[j];
a[j] = c;
}
}
}
int main()
{
int a = 1;
int b = 2;
char x = 'a';
char y = 'b';
myswap(a, b);//隐式调用
myswap<int>(a, b);//显示调用,相当于再这里告诉函数的参数类型, ,有几个类型参数<>里面就写几个
myswap(x, y);
int aa[] = { 5,2,6,4,7 };
mysort(aa, 5);
mysort<int, int>(aa, 5);//显示调用,这里就是给了原来函数参数的类型
int cc[] = { 'h','a','d','e','s' };
mysort(cc, 5);
}
2、类模板:类模板就是将类的属性类型参数化,语法与函数模板差不多
//类模板是将类的属性类型参数化,语法与函数模板差不多
#include<iostream>
using namespace std;
template<typename T>//这里告诉编译器要进行泛型编程了,并用T替代类属性的参数类型
class A {
public:
A(T a)
{
this->a = a;
}
void myprint()
{
cout << a << endl;
}
private:
T a;
};
class B :public A<int>//用到A的都要显示调用,即用到模板类的地方都显示调用,除了此类的内部
{
public:
B(int a, int b) :A<int>(a)//A的构造函数来不及调用,使用初始化列表来初始化a
{
this->b = b;
}
private:
int b;
};
//模板类继承模板类
template<typename T>
class C :public A<int>
{
public:
C(T a, T b) :A<int>(a)
{
c = b;
}
private:
T c;
};
void use(A<int>& a)//类做函数参数时,一样的要显示的定义形参,只要是泛型类,以后用到类时都要显示的调用
{
a.myprint();
}
int main()
{
A<int> a(11);//调用类时必须显示的调用,不像函数那样可以自动调用,因为编译器不知道分配什么内存。
a.myprint();
use(a);
}
3、模板的综合案例
//复数类综合案例,类模板再类外部实现函数
#include<iostream>
using namespace std;
template <typename T>
class Complex {
public:
//重载<<操作符
friend ostream& operator<<<T> (ostream& out, Complex& c3);//这里是固定写法,友元函数设计类模板都要这样写
Complex(T a, T b);
//重载+号操作符
Complex operator+(Complex& c2);
private:
T a;
T b;
};
template <typename T>//有这句的都用T代替int
Complex<T>::Complex(T a, T b)
{
this->a = a;
this->b = b;
}
template <typename T>
Complex<T> Complex<T>::operator+(Complex<T>& c2)
{
Complex<T> tmp(a + c2.a, b + c2.b);
return tmp;
}
template <typename T>
ostream& operator<<(ostream& out, Complex<T>& c3)
{
out << c3.a << "+" << c3.b << "i" << endl;
return out;
}
int main()
{
Complex<int> c1(1, 2), c2(2, 3);
Complex<int> c3 = c1 + c2;
cout << c3;
}//在模板类种,不要滥用友元函数,一般只有重载移位操作符时才用友元函数。
//static在类模板种的使用
#include<iostream>
using namespace std;
template <typename T>
class Complex {
public:
static T a;
private:
};
template<typename T>
T Complex<T>::a = 1;//注意static变量要在外部定义
int main()
{
Complex<int> c;
c.a++;
cout << Complex<int>::a << endl;
Complex<char> c1;
c1.a = 'a';
c1.a++;
cout << Complex<char>::a << endl;
}