1、函数模板:
函数模板:函数模板不是一个实在的函数,编译器不能为其生成可执行代码。定义函数模板后只是一个对函数功能框架的描述,当它具体执行时,将根据传递的实际参数决定其功能。
实例:
#include <iostream>
#include <string>
using namespace std;
template <typename T> //template 模板关键字, typename 指一个类型,可用class代替
void display(T a)
{
cout << a << endl;
}
template <typename T, class S>
void display(T t, S s)
{
cout << t << endl;
cout << s << endl;
}
template <typename T, int Ksize>
void display(T a)
{
for (int i = 0; i < Ksize; i++)
{
cout << a << endl;
}
}
int main()
{
display(10);
display<double>(10.22); //生成第一个display可执行代码并执行
display<string>("allala");
display<int, double>(5, 6.6); //生成第二个display可执行代码并执行
display<int, 6>(6); //生成第三个display可执行代码并执行
system("pause");
}
可见函数模版可根据模板参数的不同而重载。
2、类模板:
类模板与函数模板的定义和使用类似,有时,有两个或多个类,其功能是相同的,仅仅是数据类型不同,这时使用类模板就可以方便许多。
1、类模板用于实现类所需数据的类型参数化
2、类模板在表示如数组、表、图等数据结构显得特别重要,
3、这些数据结构的表示和算法不受所包含的元素类型的影响
实例1(最基本的类模板定义形式):
template < typename T>
class A
{
public:
A(T a = 0)
{
this->a = a;
}
public:
void printA()
{
cout << "a:" << a << endl;
}
protected:
T a;
};
实例2(类模板多个模板参数):
template < typename T, int size>
class A
{
public:
A(T a = 0)
{
this->a = a;
}
public:
void printA()
{
for (int i = 0; i < size; i++)
{
cout << "a:" << a << endl;
}
}
protected:
T a;
};
实例3(类模板的类外定义):
一般来说,很多idle只支持在h文件里这样做,不能分开先声明在h后在cpp定义。
#ifndef AA
#define AA
#include<iostream>
using namespace std;
template < typename T, int size>
class A;
template < typename T, int size>
class A
{
public:
A(T a = 0);
public:
void printA();
protected:
T a;
};
template < typename T, int size>
A<T, size>::A(T a)
{
this->a = a;
}
template < typename T, int size>
void A<T, size>::printA()
{
for (int i = 0; i < size; i++)
{
cout << this->a << endl;
}
}
#endif // !AA
实例4(类模板的继承):
注意以下几点:
1、当子类继承的父类是一个类模板时,子类在声明的时候要指定出父类中的类型;
2.如果不指定,编译器无法给子类分配内存;
3.如果要灵活指定父类中的T的类型,子类也需要变成模板类;
#include <iostream>
#include <string>
using namespace std;
template<typename T0>
class Father
{
public:
Father(){}
Father(T0 name) { this->name = name; }
void show() { cout << this->name << endl; }
private:
T0 name;
};
//普通子类,则需要声明时指定父类中的类型
class Son:public Father<string>
{
public:
Son(string name):Father("爸爸"){ this->name = name; }
void show() { cout << this->name << endl; }
private:
string name;
};
template<typename T1, typename T2>
class Son2 :public Father<T1>
{
public:
Son2(T2 name):Father<string>("爸爸2"){ this->name = name; }
void show() { cout << this->name << endl; }
private:
T2 name;
};
int main()
{
Son son1("儿子1");
Son2<string, int> son2(111);
son1.Father<string>::show();
son1.show();
son2.Father<string>::show();
son2.show();
}