当一个函数在一个特定的域中被多次声明时,编译器解析第二个及后面函数依照下面步骤:
1.参数个数或类型不同,则认为是重载
// 重载函数
void print( const string & );
void print( vector<int> & );
2.函数返回类型和参数表完全相同,则认为第二个函数是第一个函数的重复声明
参数表的比较过程与参数名无关
3.如果两个函数的参数表相同但是返回类型不同则第一个声明被视为第一个的错
误重复声明会被标记为编译错误,例如
unsigned int max( int i1, int i2 );
int max( int , int ); // 错误: 只有返回类型不同
函数的返回类型不足以区分两个重载函数
4.如果在两个函数的参数表中只有缺省实参不同则第二个声明被视为第一个的重
复声明例如
// 声明同一函数
int max( int *ia, int sz );
int max( int *, int = 10 );
typedef 名为现有的数据类型提供了一个替换名它并没有创建一个新类型因此如果
两个函数参数表的区别只在于一个使用了typedef 而另一个使用了与typedef 相应的类型
则该参数表不被视为不同的下列calc()的两个函数声明被视为具有相同的参数表第二个
声明导致编译时刻错误因为虽然它声明了相同的参数表但是它声明了与第一个不同的返
回类型
// typedef 并不引入一个新类型
typedef double DOLLAR;
// 错误: 相同参数表不同返回类型
extern DOLLAR calc( DOLLAR );
extern int calc( double );
当一个参数类型是const 或volatile 时在识别函数声明是否相同时并不考虑const 和
volatile 修饰符例如下列两个声明声明了同一个函数
// 声明同一函数
void f( int );
void f( const int );
参数是const 这只跟函数的定义有关系它意味着函数体内的表达式不能改变参数的
值但是对于按值传递的参数这对函数的用户是完全透明的用户不会看到函数对按值
传递的实参的改变按值传递的实参以及参数的其他传递方式在7.3 节中讨论当实参
被按值传递时将参数声明为const 不会改变可以被传递给该函数的实参种类任何int 型的
实参都可以被用来调用函数f(const int) 因为两个函数接受相同的实参集所以刚才给出的
两个声明并没有声明一个重载函数函数f()可以被定义为
void f( int i ) { }
或
void f( const int i ) { }
然而在同一个程序中同时提供这两个定义将产生错误因为这些定义把一个函数定义
了两次
但是如果把const 或volatile 应用在指针或引用参数指向的类型上则在判断函数声明
是否相同时就要考虑const 和volatile 修饰符
// 声明了不同的函数
void f( int* );
void f( const int* );
// 也声明了不同的函数
void f( int& );
void f( const
有时候没有必要重载可能也不需要不同的函数定义在某些情况下缺省实参可以
把多个函数声明压缩为一个函数中例如两个光标函数
moveAbs(int,int);
moveAbs(int,int,char*);
可以通过第三个char*型参数的有无来区分如果这两个函数的实现十分类似并且在向
函数传递参数时如果能够找到一个char*型缺省实参可以表示实参不存在时的意义则这两
个函数就可以被合并现在正好有个这样的缺省实参--值为0 的指针
move( int, int, char* = 0 );
程序员最好抱这样的观点并不是每个语言特性都是你要攀登的下一座山峰使用语言
的特性应该遵从应用的逻辑而不是简单地因为它的存在就必须要使用它程序员不应该勉
强使用重载函数只有在必要的地方使用它们才会让人感觉自