C++ 初学者指南 第六篇(10)

转载请标明出处:http://blog.csdn.net/zhangxingping

必备技能6.9:函数重载与二义性

    在结束本篇章之前,我们还有必要讨论一种C++特有的错误:二义性。二义性是指存在这样的情况:编译器不能决定应该调用重载函数中的那个。当这种情况出现的时候,我们就说程序有二义性。具有二义性的语句是一种错误,含有二义性的程序是不能被编译的。
    到目前为止,导致二义性的主要原因就是C++中的自动类型转换。C++中的自动类型转换总是试图把调用函数时传入的参数转换成函数需要的类型。下面就是一个例子:
int myfunc(double d);
//…
cout << myfunc(‘c’); //这是正确的,这里会进行自动类型转换
正如上面的注释写的那样,上面的代码是正确的。因为C++中的自动类型转换会把字符‘c’转换成一个等价的double类型。实际上,在C++中,类似于这样的自动类型转换大多数都是允许的。虽然,自动类型转换很便捷,它却是导致二义性的主要因素。看看下面的程序:

//重载引起的二义性
#include <iostream>
using namespace std;
float myfunc(float i);
double myfunc(double i);
int main()
{
    //无二义性,调用的是函数myfunc(double)
    cout << myfunc(10.1) << " ";
    //有二义性
    cout << myfunc(10); //错误!,因为编译器不能判断到底应该调用哪个myfunc()函数
    return 0;
}
float myfunc(float i)
{
    return i;
}
double myfunc(double i)
{
    return -i;
}
这里对函数myfunc()进行了重载,它可以使用float或者double类型的参数。在代码myfunc(10.1)中,传入的参数是10.1,由于C++中所有的浮点类型的常量自动地都是double类型的,所以调用的是myfunc(double),这里没有二义性。然而代码myfunc(10)是有二义性的,因为编译器不能确定是调用函数myfunc(double)还是myfunc(float)。整型数10转换成double类型或者float类型都是有效的。编译器在编译的时候会报告这种二义性错误,并停止对程序的编译。

    从上面的程序可以看出,产生二义性错误的原因并不是对函数myfunc()的重载,而是由于在调用函数的时候传入了不能确定类型的参数。
    下面是另外一个由于C++中自动类型转换而导致的二义性的程序:
//另外一个二义性程序

#include <iostream>
using namespace std;
char myfunc(unsigned char ch);
char myfunc(char ch);
int main()
{
    cout << myfunc('c');       // 这里调用的是函数myfunc(char)
    cout << myfunc(88) << " "; // 错误,有二义性
    return 0;
}
char myfunc(unsigned char ch)
{
    return ch-1;
}
char myfunc(char ch)
{
    return ch+1;
}

在C++中,unsigned char 和char 类型本质上是没有二义性的。它们是两种不相同的类型。然而当调用函数myfunc()的时候,由于传入的是整型数88,编译器就不能确定到底应该调用哪个版本的myfunc()函数了。也就是说,整型数88应该被转换为unsigned char 还是char呢?两种转换都是合法的。
    另外一种导致程序二义性的原因可能是使用了缺省函数参数。看看下面的程序:

#include <iostream>
using namespace std;
int myfunc(int i);
int myfunc(int i, int j = 1);
int main()
{
    cout << myfunc(4,5) << " "; //无二义性
    cout << myfunc(10);         //错误!有二义性
    return 0;
}
int myfunc(int i)
{
    return i;
}
在第一次调用函数myfunc()的时候,指明了两个参数,因此是没有二义性的,调用的是函数myfunc(int,int)。然而在第二次调用myfunc()的时候就产生了二义性,因为编译器不能确定到底是调用myfunc(int)还是调用有缺省参数的myfunc(int,int)。

    在继续学习C++的过程中,我们有可能会遇到二义性错误。不幸的是,在还没有程序专业的C++程序员之前,我们会发现很容易就会出现二义性的错误。

习题:
 1. 传递参数给子程序的两种方式什么?
 2. 在C++中什么是引用?如何创建引用参数?
 3. 有如下的代码:
      int f(char &c,int * i);
      //…
      char ch =’x’; int i= 10;
      写出如何调用函数f(),传入参数ch和i。
 4. 编写一个名称为round的函数,用来计算与一个double类型参数值最接近的整型数。


 

   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值