大话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&Wk7vmqP
51Testing软件测试网(| WXr v2s e4Fo*P Z jo u+G!W0
A(); //不带参数的构造函数 H5^1o\||}z ^0A(inta,int b);//带参数的构造函数 |
5i7Gg0s 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); |
而如果使用带默认参数的构造函数时就不需要不带参数的构造函数了;如下:
RH#mmE,{y p0jm-k7o^D0 51Testing软件测试网,r0K8@,U2Yi0Ex+_(F
A(int a=0,int b=0); |
则不需要在写出不带参数的构造函数了;因为你如果这样定义对象:51Testing软件测试网{ zK.gn1|6Li
51Testing软件测试网.R7E7U:KW2B+f51Testing软件测试网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软件测试网\1TAg2a-xa6dC&v6D
{51Testing软件测试网l2I.WI"{kG,vo5i8Q
public:
v0s6az1t$i0 A()
L.h^w6^t*K0 A(){data2=0;data2=0;}51Testing软件测试网UADa`!gg k!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/zr7OH%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.WUm3t
{
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;Sf G 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软件测试网CU J1hTZ ^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,oEgcA()
Xd{!k3v0 51Testing软件测试网:~Gm+u(O9VX"EpxA(){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}x H$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$jM%q0 51Testing软件测试网iWl4O UC创建这个对象时调用默认构造函数时,两个默认构造函数都符合,所以编译器不知道调用哪个!只需要把A()删掉那么两个问题就都解决了。