注意:以下所有代码均在VS2010环境下调试运行
一、模板的引入
首先,请你认真思考一个问题,如何编写一个通用的加法函数呢?
1.对于我来说,首先第一反应是写一个宏函数来实现此功能,如:
#define ADD(x,y) ((x) + (y))
那么,这样写的缺点是什么呢?
(1)它没有参数检测,这个原因致使它能够完成该要求,同时也造就了它致命的缺陷,不能进行参数检测,故安全性不高。
(2)它不能像函数一样进行调试,而仅仅是在编译期间进行简单的参数替换,况且如果代码过长,会大幅增加代码量。
(3)宏函数可能会有副作用,在不该替换的时候进行替换,假设括号没加全。
(4)宏函数只能处理整数或枚举类型的数据,对于其他追加字符串,或其他外置类型的数据处理不了。
#include<iostream>
using namespace std;
#define ADD(x,y) ((x) + (y))
int main()
{
cout<<ADD(1,3)<<endl;
cout<<ADD(1.3,2.5)<<endl;
cout<<ADD('A','G')<<endl;
system("pause");
return 0;
}
运行结果:
错误证明:
2、运用前面提到的函数重载解决通用加法函数,针对每个所需相同行为的不同类型重新实现它。
#include<iostream>
using namespace std;
int Add(const int &_iLeft, const int &_iRight)
{
return (_iLeft + _iRight);
}
float Add(const float &_fLeft, const float &_fRight)
{
return (_fLeft + _fRight);
}
int main()
{
cout<<Add(1,3)<<endl;
cout<<Add(1.3f,2.5f)<<endl;
system("pause");
return 0;
}
运行结果:
这种方法的缺点:
(1)只要有新类型出现,就要重新添加对应函数。
(2)除类型外,所有函数的函数体都相同,代码的复用率不高
(3)如果函数只是返回值类型不同,函数重载不能解决
(4)一个方法有问题,所有的方法都有问题,不好维护。
3、通过多态实现,使用公共基类,将需要用到的虚函数代码放在公共的基础类里面,通过基类的对象指针进行调用,派生类可重写也可不重写。
class B
{
public:
virtual int add(int _x,int _y)
{
return (_x+_y);
}
virtual float add(float _x,float _y)
{
return (_x+_y);
}
};
class INT_ADD:public B
{};
class FLOAT_ADD:public B
{};
int main()
{
B *b;
INT_ADD i;
FLOAT_ADD f;
b = &i;
cout<<b->add(1,3)<<endl;
b = &f;
cout<<b->add(1.8f,3.6f)<<endl;
system("pause");
return 0;
}
运行结果:
缺点:
(1)借助基类虚函数来编写适合各种类型的加法函数,只要有新类型出现,就要重新添加对应函数,代码利用率不高;(2)对于以后实现的许多派生类,都必须调用各自某个特定的基类虚函数,代码维护更加困难。
4、通过模板解决。
模板的分类:模板分为函数模板和类模板,他们分别允许用户构造模板函数和模板类。
既然上面的几种方法都有各自的缺陷,于是就引入了模板的概念,使用我们的模板解决上述问题,那将是最好不过了,下面用函数模板实现通用加法函数。
template <typename T>
T ADD(T x,T y)
{
return (x+y);
}
int main()
{
cout<<ADD(1,3)<<endl;
cout<<ADD(1.3,2.5)<<endl;
system("pause");
return 0;
}
运行结果: