`
duoerbasilu
  • 浏览: 1483321 次
文章分类
社区版块
存档分类
最新评论

C/C++--C++默认参数及其所引起的二义性

 
阅读更多

先来了解默认参数是什么吧!

默认参数是指在定义或声明函数时,为参数指定默认值,在调用函数时,可以传递参数,也可以不传递参数;如果没有

传递参数,则在函数中使用默认参数的默认值!

对于默认参数不要单纯的错误的理解为就是函数的参数带有一个默认值,其实他强调的不仅是参数的默认的值还有如果

没有传递参数可以使用默认的参数;也就是说你调用函数时可以不带参数,却仍然能正常运行(这是用的就是默认参数的默

认值);因为编译器会自动调用默认参数

最典型的就是在带默认参数的构造函数:

比如说你定义了一个class A; A有两个private数据成员int a;和int b;如果不是用默认的构造函数的话代码如下:

A(); //不带参数的构造函数

A(inta,int b);//带参数的构造函数

如果你在新建对象时,如初始化

A a1; //初始化调用A();

A a2(3,4); //赋值调用A(int a,int b);


而如果使用带默认参数的构造函数时就不需要不带参数的构造函数了;如下:

A(int a=0,int b=0);

则不需要在写出不带参数的构造函数了;因为你如果这样定义对象:

A a1; //调用的还是A(inta=0,int b=0)因为编译器就不再产生默认的构造函数A();而是直接调用A(int a=0,int b=0)

//因为没有实参的构造函数,是默认构造函数,参数指定了默认值的构造函数也是默认构造函数,一个类只能有一个默认构造函数

这里要说明的是一个类在写了默认构造函数之后就不会自动生成默认的构造函数,如果你写的是带默认参数的构造函数,则其实已经有了默认构造函数,如果在定义一个就会出现在A()就会出错了!看看下面的代码吧!

例如:

#include<iostream>
#include<string>
using namespace std;
class A
{
public:
    A()
    A(){data2=0;data2=0;}
    A(int a=0,int b=0){data1=a;data2=b;}
    void display();
private:
    int data1;
    int data2;
};
void A::display()
{
    cout<<data1<<endl;
    cout<<data2<<endl;
}
void main()
{
    A a1;
    A a2(1,2);
    a1.display();
    a2.display();
}




编译后会出现错误是(用的VS2010)

C++1>f:\面向对象\miao_9\miao_9\12.cpp(8): error C2535: “A::A(void)”: 已经定义或声明成员函数

1>f:\面向对象\miao_9\miao_9\12.cpp(7) : 参见“A::A”的声明

1>f:\面向对象\miao_9\miao_9\12.cpp(14): warning C4520: “A”: 指定了多个默认构造函数

1>f:\面向对象\miao_9\miao_9\12.cpp(22): error C2668: “A::A”: 对重载函数的调用不明确

1>f:\面向对象\miao_9\miao_9\12.cpp(9): 可能是“A::A(int,int)”

1>f:\面向对象\miao_9\miao_9\12.cpp(7): 或 “A::A(void)”



现在解释下上面的错误出现的原因吧:首先要说的就是“指定了多个默认构造函数”

A()

A(){data2=0;data2=0;}



如上所说的这两个都是默认构造函数,而一个类只能调用一个默认构造函数(一定要注意带默认参数的构造函数也是默认构造函数!)

在就是

对重载函数的调用不明确

也就是所说的二义性啊,因为编译器不知道调用哪个默认的构造函数啊!

A a1;

创建这个对象时调用默认构造函数时,两个默认构造函数都符合,所以编译器不知道调用哪个!只需要把A()删掉那么两个问题就都解决了。

现在在举个函数重载时二义性例子:

#include<iostream>
using namespace std;
int max(int a,int b);
int max(int a=0,int b=0,int c=0);  //函数重载
void main()
{
        inta=2;
        intb=3;
        cout<<max(a,b)<<endl;
}
int max(int a,int b)
{
        if(a>b)
               returna;
        else
               returnb;
}



编译后报错如下(VS2010):

C++1> 正在创建“Debug\miao_12.unsuccessfulbuild”,因为已指定“AlwaysCreate”。

1>ClCompile:

1> 2.cpp

1>f:\面向对象\miao_12\miao_12\2.cpp(9): error C2668: “max”: 对重载函数的调用不明确

1> f:\面向对象\miao_12\miao_12\2.cpp(4): 可能是“int max(int,int,int)”

1> f:\面向对象\miao_12\miao_12\2.cpp(3): 或 “int max(int,int)”

1> f:\visualstudio\vc\include\xutility(2078): 或 “const _Ty &std::max<int>(const _Ty&,const _Ty &)”

1> with



“函数重载调用不明确”也就是在调用max(a,b)时两个

int max(int a,int b);
int max(int a=0,int b=0,int c=0);  //函数重载



在语法上调用都是合法的,所以才会出现调用不明确啊,对于int max(int a,int b)无可非议,调用他是合法的。而对于int max(int a=0,int b=0,int c=0)也是符合语法的,这就是C++的默认参数效果,因为C++对于使用默认参数的函数是不一定传递函数的参数,也就是说参数是可以省略的!至于怎么改就不在赘述了,,,,

说道这里,应该差不多了吧!呵呵,,还是那句老话,对于有不对之处,还望指出!

参考书目《面向对象程序设计(C++版)》


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics