Impossible is nothing  
  爱过知情重醉过知酒浓   花开花谢终是空   缘份不停留像春风来又走   女人如花花似梦
公告
日历
<2024年12月>
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234
统计
  • 随笔 - 8
  • 文章 - 91
  • 评论 - 16
  • 引用 - 0

导航

常用链接

留言簿(4)

随笔分类(4)

随笔档案(8)

文章分类(77)

文章档案(91)

相册

搜索

  •  

最新评论

阅读排行榜

评论排行榜

 
  

一个函数在一个特定的域中被多次声明时,编译器解析第二个及后面函数依照下面步骤:

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 );
程序员最好抱这样的观点并不是每个语言特性都是你要攀登的下一座山峰使用语言
的特性应该遵从应用的逻辑而不是简单地因为它的存在就必须要使用它程序员不应该勉
强使用重载函数只有在必要的地方使用它们才会让人感觉自

using 声明怎样影响重载函数呢using 声明为一个名字空间的成员在该声明出现的域中
提供了一个别名下面程序中的using 声明会怎么样呢
namespace libs_R_us {
int max( int, int );
int max( double, double );
extern void print( int );
extern void print( double );
}
// using 声明
using libs_R_us::max;
using libs_R_us::print( double ); // 错误
void func()
{
max( 87, 65 ); // 调用 libs_R_us::max( int, int )
max( 35.5, 76.6 ); // 调用 libs_R_us::max( double, double )
}
第一个using 声明向全局域中引入了两个libs_R_us::max()函数于是我们便可以在func()
中调用这两个max()函数函数调用时的实参类型将决定哪个函数会被调用第二个using 声
明是个错误用户不能在using 声明中为一个函数指定参数表对于libs_R_us::pring()惟一有
效的using 声明是
using libs_R_us::print;


如果using 声明向一个域中引入了一个函数而该域中已经存在一个同名的函数又会
怎样呢记住using 声明只是一个声明由using 声明引入的函数就好像在该声明出现的地
方被声明一样因此由using 声明引入的函数重载了在该声明所出现的域中同名函数的其
他声明例如
375 第九章 重载函数
#include <string>
namespace libs_R_us {
extern void print( int );
extern void print( double );
}
extern void print( const string & );
// libs_R_us::print( int ) 和 libs_R_us::print( double )
// 重载 print( const string & )
using libs_R_us::print;
void fooBar( int ival )
{
print( "Value: " ); // 调用全局 print( const string & )
print( ival ); // 调用 libs_R_us::print( int )
}
using 声明向全局域中加入了两个声明一个是print(int) 一个是print(double) 这些声
明为名字空间libs_R_us 中的函数提供了别名这些声明被加入到print()的重载函数集合中
它已经包含了全局函数print(const string&) 当fooBar()调用函数时所有的print()函数都将
被考虑


如果using 声明向一个域中引入了一个函数而该域中已经有同名函数且具有相同的参
数表则该using 声明就是错误的如果在全局域中已经存在一个名为print(int)的函数则
using 声明不能为名字空间libs_R_us 中的函数声明别名print(int) 例如
namespace libs_R_us {
void print( int );
void print( double );
}
void print( int );
using libs_R_us::print; // 错误: print(int) 的重复声明
void fooBar( int ival )
{
print( ival ); // 哪一个 print? ::print 还是 libs_R_us::print?
}


posted on 2006-02-22 22:47 笑笑生 阅读(214) 评论(0)  编辑 收藏 引用 所属分类: C++语言

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理


 
Copyright © 笑笑生 Powered by: 博客园 模板提供:沪江博客