C++入门学习——模板

为什么需要模板?

我们已经学过重载(Overloading),对重载函数而言,C++ 通过函数参数(参数个数、参数类型)的正确匹配来调用重载函数。例如,为求两个数的最大值,我们定义 max () 函数需要对不同的数据类型分别定义不同重载(Overload)版本。

//函数1
int max(int x, int y);
{
	return(x>y)?x:y ;
}

//函数2
float max( float x, float y)
{
	return (x>y)?x:y ;
}

//函数3
double max(double x, double y)
{
	return (c>y)?x:y ;
}

现在,我们再重新审视上述的 max() 函数,它们都具有同样的功能,即求两个数的最大值,能否只写一套代码解决这个问题呢?这样就会避免因重载函数定义不全面而带来的调用错误(如,我们分别定义了 char a,b; 那么在执行 max(a,b) 时 程序就会出错,因为我们没有定义char 类型的重载版本)。


同样的,对于类而言,也存在同样的问题(基本上是重复性的工作):

//对两个整数作比较
class Compare_int
{
public:
	Compare(int a,int b){x=a;y=b;}
	int max( ) {return(x>y)?x:y;}
	int min( ) {return(x<y)?x:y;}
private:
	int x,y;
};

//对两个浮点数作比较
class Compare_float
{
public:
	Compare(float a,float b) {x=a;y=b;}
	float max( ) {return(x>y)?x:y;}
	float min( ) {return(x<y)?x:y;}
private:
	float x,y;
}


为解决上述问题 C++ 引入模板机制:模板就是实现代码重用机制的一种工具,它可以实现类型参数化,即把类型定义为参数, 从而实现了真正的代码可重用性。模版可以分为两类,一个是函数模版,另外一个是类模版


函数模板

函数模板的一般形式如下:

template <class 形参名, class 形参名, ……> 返回类型 函数名(形参表)

{

//函数定义体 

}

其中 template 和 class 是关键字,class 可以用 typename 代替,在这里 typename 和 class 没区别,<> 括号中的参数叫模板形参,模板形参和函数形参很相像,模板形参不能为空。


一但声明了类模板,函数中使用内置类型的地方都可以使用模板形参名来声明。模板形参需要调用该模板函数时提供的模板实参来初始化模板形参,一旦编译器确定了实际的模板实参类型就称他实例化了函数模板的一个实例。

template <class T> void swap(T& a, T& b)
{
	//……
}

当调用这样的模板函数时类型 T 就会被被调用时的类型所代替,比如 swap(a,b) 其中 a 和 b 是 int  型,这时模板函数 swap 中的形参 T 就会被 int 所代替,模板函数就变为 swap(int &a, int &b)。而当 swap(c,d) 其中 c 和 d 是 double 类型时,模板函数会被替换为swap(double &a, double &b),这样就实现了函数的实现与类型无关的代码。

示例代码如下:

#include <iostream>
using std::cout;
using std::endl;

//声明一个函数模版,用来比较输入的两个相同数据类型的参数的大小,
//class也可以被typename代替,
//T可以被任何字母或者数字代替。

//template <typename T>
template <class T> T max(T x,T y)
{ 
	return(x>y)?x:y;
}

int main()
{

    int a=2, b=10;
    cout<< "较大整数:"<<max(a, b)<<endl;
	
	double m=1.5, n=5.6;
    cout<< "较大实数:"<<max(m, n)<<endl;
	
	return 0;
}


运行结果如下:


类模板

类模板的一般形式如下:

template <class 形参名, class 形参名, ……>   class 类名

//类定义... 

};


一但声明了类模板就可以用类模板的形参名声明类中的成员变量和成员函数,即可以在类中使用内置类型的地方都可以使用模板形参名来声明。比如:

template <class T> class A
{
public: 
	T a; 
	T b; 
	T hy(T c, T &d);
};

在类 A 中声明了两个类型为T的成员变量 a 和 b,还声明了一个返回类型为 T 带两个参数类型为 T 的函数 hy。


类模板对象的创建:比如一个模板类 A,则使用类模板创建对象的方法为 A<int> m;在类 A 后面跟上一个 <> 尖括号并在里面填上相应的类型,这样的话类 A 中凡是用到模板形参的地方都会被 int  所代替。当类模板有两个模板形参时创建对象的方法为 A<int, double> m;类型之间用逗号隔开。


在类模板外部定义成员函数的方法为:

template<模板形参列表> 函数返回类型 类名<模板形参名>::函数名(参数列表){函数体}


比如有两个模板形参 T1,T2 的类 A 中含有一个 void h() 函数,则定义该函数的语法为:

template<class T1, class T2> class A
{
public: 
	void h();
};

template<class T1,class T2> void A<T1,T2>::h()
{
	// ……
}


注意:模板的声明或定义只能在全局,命名空间或类范围内进行。即不能在局部范围,函数内进行,比如不能在 main() 函数中声明或定义一个模板。


示例代码如下:

#include <iostream>
using namespace std;

template <class numtype> class Compare //类模板
{
public:
	//Compare(numtype a,numtype b){x=a;y=b;}
	Compare(numtype a,numtype b);
	numtype max(){return (x>y)?x:y;}
	numtype min(){return (x<y)?x:y;}
private:
	numtype x,y;
};

template <class numtype> Compare<numtype>::Compare(numtype a,numtype b)
{
	x=a;
	y=b;
}


int main( )
{
	Compare<int>cmp1(3,7); //定义对象cmp1,用于两个整数的比较
	cout << cmp1.max() << " is the Maximum" << endl;
	cout << cmp1.min() << " is the Minimum" << endl << endl;
	
	Compare<float> cmp2(45.78,93.6); //定义对象cmp2,用于两个浮点数的比较
	cout << cmp2.max() << " is the Maximum" <<endl;
	cout << cmp2.min() << " is the Minimum" <<endl<<endl;
	
	Compare<char> cmp3('a', 'A'); //定义对象cmp3,用于两个字符的比较
	cout << cmp3.max() << " is the Maximum" <<endl;
	cout << cmp3.min() << " is the Minimum" <<endl;
	
	return 0;
}

运行结果如下:



本教程示例代码下载请点此处。


参考资料:

http://www.cnblogs.com/gw811

http://www.cnblogs.com/gaojun

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值