本文目的:理解并掌握类模板
参考资源:c++ primer
模板是一个非常有用的东西,可以让我们写一次代码产生出不同的版本以应对不同的数据类型,原理是在具体调或者是在编译时产生不同的版本。类模板是对一批仅仅成员数据类型不同的类的抽象,程序员只要为这一批类所组成的整个类家族创建一个类模板,给出一套程序代码,就可以用来生成多种具体的类,(这类可以看作是类模板的实例),从而大大提高编程的效率。
使用格式为:
template<class T> or template<typename T>
这里的class与typename 没有区别,前者要老一些,后者更直观一点的表明后面跟的是个类型名。
一,函数模板:例:
template<class T>
compare( const T &a, const T &b)
{
}
说明:模板声明中跟在class and typename 后面的叫类型形参,跟在其它声明比如 int 或是其它自定义类型后面的叫作非类型形参。
使用函数模板时可以直接调用如:compare(1,3);编译器会自动生成相应的版本。
inline 模板函数的声明中inline 要放在<>后,如:
template<class T>
inline T compare( const T &a, const T &b)
{ }
模板函数简单举例1:
#include "StdAfx.h"
#include <iostream>
using namespace std;
template<typename T> //模板声明,其中T为类型参数
T max(T a,T b,T c) //定义一个通用函数,用T作虚拟的类型名
{ //这个函数所有参数以及返回值均是T类型
if(b>a) a=b;
if(c>a) a=c;
return a;
}
int main( )
{
int i1=185,i2=-76,i3=567,i;
double d1=56.87,d2=90.23,d3=-3214.78,d;
long g1=67854,g2=-912456,g3=673456,g;
i=max(i1,i2,i3); //调用模板函数,此时T被int取代
d=max(d1,d2,d3); //调用模板函数,此时T被double取代
g=max(g1,g2,g3); //调用模板函数,此时T被long取代
cout<<"i_max="<<i<<endl; cout<<"f_max="<<d<<endl; cout<<"g_max="<<g<<endl;
system("pause");
return 0;
}
模板函数简单举例2:
#include "iostream"
using namespace std;
template<class T>
void PrintArray(T *Array,int count)
{
for(int i=0;i<count;i++)
cout<<Array[i]<<" ";
cout<<endl;
}
int main()
{
int a[5]={1,2,3,4,5};
double b[7]={1.1,2.2,3.3,4.4,5.5,6.6,7.7};
char c[6]="HELLO";
PrintArray(a,5);
PrintArray(b,7);
PrintArray(c,6);
system("pause");
return 0;
}
二,类模板:
//1. 标准模板类。
template<typename T1, typename T2>
class MyClass {
... ...
};
//2. 两个模板参数具有相同类型的部分特化类。
template<typename T>
class MyClass<T,T> {
... ...
}
//3. 第二个类型参数是int
template<typename T>
class MyClass<T,int> {
... ...
}
//4. 两个模板参数都是指针。
template<typename T1,typename T2>
class MyClass<T1*,T2*> {
... ...
}
//5. 两个模板参数都是相同类型的指针。
template<typename T>
class MyClass<T*,T*> {
... ...
}
//6. 调用示例代码。
int main() {
MyClass<int,float> c1; //调用MyClass<T1,T2>
MyClass<float,float> c2; //调用MyClass<T,T>
MyClass<float,int> c3; //调用MyClass<T,int>
MyClass<int*,float*> c4; //调用MyClass<T1*,T2*>
MyClass<int*,int*> c5; //调用MyClass<T*,T*>
return 0;
}
类模板简单举例1:
#include "StdAfx.h"
#include <iostream>
using namespace std;
template <typename T>
class classOne
{
private:
T a;
public:
T get(T b)
{
a=b*b;//平方化
return a;
}
};
template <typename TT>
class classTwo
{
private:
classOne<TT> test;//在类classTwo中声明成员变量,意在调用通过此成员变量调用另一个类的成元函数
public:
TT out(TT b)
{
return test.get(b);
}
};
int main()
{
classTwo<double> test2;//传过去
cout<<test2.out(3.2)<<endl;
system("pause");
return 0;
}
类模板的使用与函数模板有所不同,在调用类模板时必须显式的指定类型形参T,如我们定义的A的使用:
A< int > ai;
A< char > ac;
A< vector<double> > av;
A< string > as;
(1)关于形参,模板形参在其作用域中会屏蔽掉全局参数。
(2)形参的名字不能在模板内部重用,也就是说一个名字在一个模板中只能使用一次:
template<class u, class u> //error
但是可以这样(多个类型参数)
template <class T1, typename T2>
(3)模板的声明和定义中参数的名字可以不同如:
声明:
template<class U>
class A
定义:
template<class T>
class A{}