大话C++——默认参数及其所引起的二义性

上一篇 / 下一篇  2012-08-03 10:07:29 / 个人分类:C++

n?2ae [%b+jS0  先来了解默认参数是什么吧!51Testing软件测试网%xI!@ c#P

51Testing软件测试网jjvL$iD WT

  默认参数是指在定义或声明函数时,为参数指定默认值,在调用函数时,可以传递参数,也可以不传递参数;如果没有传递参数,则在函数中使用默认参数的默认值!51Testing软件测试网I\HZ:t T

51Testing软件测试网.uV Z+PL

  对于默认参数不要单纯的错误的理解为就是函数的参数带有一个默认值,其实他强调的不仅是参数的默认的值还有如果没有传递参数可以使用默认的参数;也就是说你调用函数时可以不带参数,却仍然能正常运行(这是用的就是默认参数的默认值);因为编译器会自动调用默认参数。

Sx/V8X:Sb\E0 51Testing软件测试网D ee-LA}i/m`^1i

  最典型的就是在带默认参数的构造函数:51Testing软件测试网oC X']$}q

51Testing软件测试网1C S1S%c5];M9C

  比如说你定义了一个class A;A有两个private数据成员int a;和int b;如果不是用默认的构造函数的话代码如下:51Testing软件测试网0H!O&Wk7vmq P

51Testing软件测试网(| WXr v2s e4F

o*P Z jo u+G!W0
A();           //不带参数的构造函数
H5^1o\||}z ^0A(inta,int b);//带参数的构造函数

5i7G g0s O*]!K| Y7y+O \0  如果你在新建对象时,如初始化51Testing软件测试网 C:Z:sC3G P*}'m~r

:HL#{*`|0 51Testing软件测试网+_D"[J/B{ K2P

A a1;         //初始化调用A();51Testing软件测试网)}.n.\+`E8S
A a2(3,4);    //赋值调用A(int a,int b);
51Testing软件测试网]|H] i2L[3Q

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

RH#mmE,{y p0

jm-k7o^ D0 51Testing软件测试网,r0K8@,U2Yi0Ex+_(F

A(int a=0,int b=0);
51Testing软件测试网0A6mxv1mZ

  则不需要在写出不带参数的构造函数了;因为你如果这样定义对象:51Testing软件测试网{zK.gn1|6Li

51Testing软件测试网.R7E7U:KW2B+f

51Testing软件测试网Sh#i!^!a(gfI8pv7Os

A a1;           //调用的还是A(inta=0,int b=0)因为编译器就不再产生默认的构造函数A();而是直接调用A(int a=0,int b=0)
j8xS/z/Fd/r3S0                //因为没有实参的构造函数,是默认构造函数,参数指定了默认值的构造函数也是默认构造函数,一个类只能有一个默认构造函数

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

h|{ c yh)jk(O5ZO`0 51Testing软件测试网t3s9TZ4?Y-c@

  例如:51Testing软件测试网n:mnb\$^;JK

"}\B0@!De6h/J Y-w0 51Testing软件测试网VuP7w*c6P+^~ o

#include<iostream>
1f(k;l ^(}x.\ _0uPp0#include<string>51Testing软件测试网:Cs+Y6?%D
using namespace std;51Testing软件测试网7Zw]Y%h2Q)S
class A51Testing软件测试网\1T Ag2a-xa6dC&v6D
{51Testing软件测试网l2I.WI"{kG,vo5i8Q
public:
v0s6az1t$i0    A()
L.h^w6^t*K0    A(){data2=0;data2=0;}51Testing软件测试网UADa`!ggk!Z
    A(int a=0,int b=0){data1=a;data2=b;}51Testing软件测试网(Lgb#F @'SO"K
    void display();51Testing软件测试网%ee%V \ \
private:
V8k ^.l6I:@-jPZ0    int data1;51Testing软件测试网9{-or.f][:H
    int data2;51Testing软件测试网lB5l/z r7OH%P9n6e+T
};51Testing软件测试网 r4W8|:|*\uT B-O
void A::display()51Testing软件测试网[C&z Af
{51Testing软件测试网9_1SR&y[{Rs7A
    cout<<data1<<endl;
E _w*\]`0    cout<<data2<<endl;
s:[$u1y:p&il5F0}51Testing软件测试网#ws8s#y4g b
void main()51Testing软件测试网 WcH.W Um3t
{
r:v3yE NL!T+I0    A a1;
cu8q7iUU M0Dr0    A a2(1,2);51Testing软件测试网`M,?f e1j3fmw}
    a1.display();
r_TD#{I0dksx0    a2.display();
h!} t6t1p qT0}51Testing软件测试网h$o o6p s
51Testing软件测试网C j,edr'@.p7_$P0{ f F

  编译后会出现错误是(用的VS2010)51Testing软件测试网I8}"iMh*rz

51Testing软件测试网wC.[5Ja;SfG

  C++1>f:\面向对象\miao_9\miao_9\12.cpp(8): error C2535: “A::A(void)”: 已经定义或声明成员函数
K:|.^hj!_'B0  1>         f:\面向对象\miao_9\miao_9\12.cpp(7) : 参见“A::A”的声明
+a'yq$s0g-C0  1>f:\面向对象\miao_9\miao_9\12.cpp(14): warning C4520: “A”: 指定了多个默认构造函数51Testing软件测试网CUJ1hT Z ^h s"raf!R
  1>f:\面向对象\miao_9\miao_9\12.cpp(22): error C2668: “A::A”: 对重载函数的调用不明确51Testing软件测试网(bk9Ju:A;j/e1`5yB
  1>         f:\面向对象\miao_9\miao_9\12.cpp(9): 可能是“A::A(int,int)”51Testing软件测试网!fP;^ Y-S#R
  1>         f:\面向对象\miao_9\miao_9\12.cpp(7): 或       “A::A(void)”
51Testing软件测试网;Sb\'J&v;@@U

,^:b,P"{yg*}0  现在解释下上面的错误出现的原因吧:首先要说的就是“指定了多个默认构造函数”51Testing软件测试网N@zB'b{

51Testing软件测试网)kU[0j,oEgc

  A()

Xd{!k3v0 51Testing软件测试网:~Gm+u(O9VX"Epx

  A(){data2=0;data2=0;}51Testing软件测试网5` p9Xgfi2X X

;Pq\#m&Od/iZ2@+]g0  如上所说的这两个都是默认构造函数,而一个类只能调用一个默认构造函数(一定要注意带默认参数的构造函数也是默认构造函数!)

x:F;X h8Y1m-c6y0 51Testing软件测试网{+~ _4c%k`fpe

  在就是51Testing软件测试网p+G}q8fI"\dM

51Testing软件测试网 C}xH$w;f6J g{^M

  对重载函数的调用不明确

;Y/h{.~'[Y"p0bOn6|0o0

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

bl:]kd;y_E0 51Testing软件测试网%u&K^W!C+w6QQ6{

  A a1;

.T1h#g$j M%q0 51Testing软件测试网iWl4O UC

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

j](MP)R:P0 51Testing软件测试网ny}SDE)M2c%c*y6o

  现在在举个函数重载时二义性例子:51Testing软件测试网2y3WuCv;g)_

51Testing软件测试网"Q4uo]lI

9W'bo&YH"l0
#include<iostream>
9HS'm6z_"~0using namespace std;
"A oL;t"LJP)o7Y0int max(int a,int b);
9z.I&|vU$F0int max(int a=0,int b=0,int c=0);  //函数重载51Testing软件测试网 \/N6D)H&w^ A l-h'e
void main()51Testing软件测试网G%S$kkTnJ {^u
{
R&A4\,J-A SC3^&I5A0        inta=2;
"mb n A n$SI a0        intb=3;
1_1@-Eq1[a:y-V0        cout<<max(a,b)<<endl;
1{X-P&_F#_]6K0}51Testing软件测试网 \YSO3R;s/k$E
int max(int a,int b)
%`1A{YN0{51Testing软件测试网a%` uz;o.k?'S
        if(a>b)51Testing软件测试网*`UZG5H'S G} B
               returna;
{I jR,V*Ad(ye9v0o;h0        else51Testing软件测试网'Y}t\8nJ
               returnb;
(g-yS.V%t3y5b'N0}
51Testing软件测试网f+c$e"N q

  编译后报错如下(VS2010):

a i M r D6X+r0

!l1Hm? YU!T0  C++1>  正在创建“Debug\miao_12.unsuccessfulbuild”,因为已指定“AlwaysCreate”。51Testing软件测试网l-fl+YXG'Y*lB md
  1>ClCompile:51Testing软件测试网] N:H8E6J%]B2[C
  1>  2.cpp
~ j K)UAN"|$A0  1>f:\面向对象\miao_12\miao_12\2.cpp(9): error C2668: “max”: 对重载函数的调用不明确
?4HU/m/an0  1>         f:\面向对象\miao_12\miao_12\2.cpp(4): 可能是“int max(int,int,int)”51Testing软件测试网 g |2\DUg
  1>         f:\面向对象\miao_12\miao_12\2.cpp(3): 或       “int max(int,int)”
H:Y#W4~#J%x&l J&XJ1E~0   1>         f:\visualstudio\vc\include\xutility(2078): 或       “const _Ty &std::max<int>(const _Ty&,const _Ty &)”51Testing软件测试网1C EL,j:BIw
  1>         with
51Testing软件测试网&VM+T U q'p$V `

\&W1@V:L+q'`Y7g0  “函数重载调用不明确”也就是在调用max(a,b)时两个

r1})HSw1l)v/Z0

K @/y3] \%[0k0 51Testing软件测试网4D_x JL

int max(int a,int b);
7d Jx|YS2zO]{0int max(int a=0,int b=0,int c=0);  //函数重载
51Testing软件测试网N9w"f-ZV@AtjQ-^

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

51Testing软件测试网7kE5pz m v)a"V

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

0M^ @]C C.T%c]}0
-QL ?e|wve;Vp0

TAG:

 

评分:0

我来说两句

Open Toolbar