它将实现数据求和功能而输出:
但我们至少有一打理由拒绝使用它,以下是最明显的:
①宏缺少类型安全检测,如:
ADD ('A' 0. 0l);
这样的调用将被解释为合法,而事实上,很少的用户期望能写出这样的语句;
②宏不会为参数引入临时拷贝,如:
#define DOUBLE (x)((x)+(x))
int i(1);
cout<<DOUBLE(i++); //prints '3'
|
③宏不具有地址,例如可能在一个计算器程序中有:
case ' +': Operator = & ADD;
并不能得到合理解释。
采取函数?然而,使用函数并不是最划算的支出,它浪费了宝贵的执行时间。使用过汇编语言的读者可能知道,一般函数执行真正的函数体前后,要做一些现场保护工作,当函数体积很小时,这种冗余的工作量将会远远大于函数本身。
为此,C++提供了关键字inline,当用户希望编译器将某函数的代码直接插入到调用点时,可将其设置成inline函数,即在函数定义时加上关键字inline,如:
//test09.cpp
#include <iostream.h>
inline int Add (int a int b)
{
return a + b;
}
void main O)
{
cout<<"1+2=“<<Add(1 2);
}
|
主函数将被编译器解释为:
count<<"1+2=”<<{1+2 };
其行为完全类似于前例的ADD (a b)宏。经验表明,将使用频繁而且体积很小的函数声明为inline是明智的。
3.函数重载(overload)
在实际数据求和操作时,如上节内容中提供的Add()函数是远远不够的,你不得不再添加一些其它代码,如:
double AddDouble(double a double b)
{
return a + b;
}
float AddFloat (float a float b )
{
return a + b;
}
|
特别地,在C++中你可以玩弄名字的技巧,将以上的AddDouble AddFloat皆取名为Add,如:
double Add(double a double b)
{
return a + b;
}
|
尽管放心,编译器会安全地为不同的调用形式找到相应的函数原型。如:
double a b;
Add(f 2); //int Add(int int)
Add (a b); //double Add (doubledouble)
|
这样,不同的函数拥有相同的函数名,即函数重载。函数重载以及后面的模板、虚函数机制形成了“一个接口,多种功能”的特性,即多态性(polymorphism),它是面向对象(OO)的技术之一。
在使用重载机制时,C++提出了许多防止二义性的限制,如:
void fun(int a);
int fun(int a);
void fun(int& a);
void fun (int a int b=0);
|
很可能引起C ++编译器的恐慌,它在遇到诸如fun(100)的调用时会十分不满。用户有义务保证任一调用形式不产生二义性。以下是一种常见的使用重载机制的例程:
//test10.cpp
#include <graphics.h>
#include <iostream.h>
void Pixel(int x int y int color)
{
putpixel(x y color);
}
int Pixel(int x int y)
{
return getpixel(x y);
}
void main()
{
int Driver=VGA Mode=VGAHI;
initgraph(&Driver &Mode "");
Pixel(100 100 4);
int Color = Pixel(100 100);
closegraph();
cout << "Color of point(100 100):" << Color;
}
|
可以想象C++将以上不同的Pixel()函数分别编码为Pixel_iii和Pixel_ii,它的形式包含了各入口参数的数据类型。注意,编码未包含返回值的信息,因而依赖于返回值类型的差异的函数重载是不稳定的。因此,连接器(linker)可以毫不费力地找到相应的模块。但这对于新旧C版本产生的模块连接恐怕添加了麻烦,因为传统的C函数库中并没有对函数名再作手脚的坏习惯,C++不得不提供关键字extern来保证这种连接的安全性,如下形式(注意’C’可要大写):
extern "C"
{
void Pixel(int x int y int Color);
};
|
将告诉编译器只需要在函数库中找相应的Pixel模块,而不必自作聪明。而
extern "C"
{ //' #include’一定要另起一行
#include "function. h"
};
|
则声明包含在头文件function. h中所有函数模块皆采取C连接。
T111