示例:
#include <iostream>
using namespace std;
class Box
{
public:
Box(int h = 10, int w = 10, int len = 10); //在声明构造函数时指定默认参数
Box(float h=10,float w=15);
int volume();
private:
int height;
int width;
int length;
};
Box::Box(int h, int w, int len) //在定义函数时可以不指定默认参数
{
height = h;
width = w;
length = len;
}
int Box::volume()
{
return (height*width*length);
}
int main()
{
/*Box box1; //没有给实参
cout << "The volume of box1 is " << box1.volume() << endl;*/
Box box2(15); //只给定一个实参
cout << "The volume of box2 is " << box2.volume() << endl;
Box box3(15, 30); //只给定2个实参
cout << "The volume of box3 is " << box3.volume() << endl;
Box box4(15, 30, 20); //给定3个实参
cout << "The volume of box4 is " << box4.volume() << endl;
return 0;
}
程序运行结果为:
The volume of box1 is 1000
The volume of box2 is 1500
The volume of box3 is 4500
The volume of box4 is 9000
程序中对构造函数的定义也可以改写成参数初始化表的形式:
Box::Box(int h,int w,int len):height(h),width(w),length(len){ }
可以看到,在构造函数中使用默认参数是方便而有效的,它提供了建立对象时的多种选择,它的作用相当于好几个重载的构造函数。它的好处是,即使在调用构造函数时没有提供实参值,不仅不会出错,而且还确保按照默认的参数值对对象进行初始化。尤其在希望对每一个对象都有同样的初始化状况时用这种方法更为方便。
关于构造函数默认值的几点说明:
应该在声明构造函数时指定默认值,而不能只在定义构造函数时指定默认值。这样是有很大的好处,一方面可以是默认的参数值,另外一方面在特别需要的时候进行修改,相当于前面所说的重载
在声明构造函数时,形参名可以省略。
如果构造函数的全部参数都指定了默认值,则在定义对象时可以给一个或几个实参,也可以不给出实参。
在一个类中定义了全部是默认参数的构造函数后,不能再定义重载构造函数。
这一条是什么意思呢??????
上面我不是已经重载构造函数,而且没有出错a,这么说的原因主要是针对
Box box1; //没有给实参 这种情况,程序调用构造函数的时候就会出现二义性的问题
<pre name="code" class="cpp">Box(int h=10,int w=15); //要是在函数上面添加这个语句,那么结果就是会出错,因为下面有一个参数和两个参数的,不知道调用哪个构造函数了
#include <iostream>
using namespace std;
class Box
{
public:
Box(int h = 10, int w = 10, int len = 10); //在声明构造函数时指定默认参数
Box(int h=10,int w=15);
int volume();
int volume1();
private:
int height;
int width;
int length;
};
Box::Box(int h, int w, int len) //在定义函数时可以不指定默认参数
{
height = h;
width = w;
length = len;
}
Box::Box(int h, int w) //在定义函数时可以不指定默认参数
{
height = h;
width = w;
}
int Box::volume()
{
return (height*width*length);
}
int Box::volume1()
{
return (height*width);
}
int main()
{
/*Box box1; //没有给实参
cout << "The volume of box1 is " << box1.volume() << endl;*/
Box box2(15); //只给定一个实参
cout << "The volume of box2 is " << box2.volume() << endl;
Box box3(15, 30); //只给定2个实参
cout << "The volume of box3 is " << box3.volume() << endl;
Box box4(15, 30, 20); //给定3个实参
cout << "The volume of box4 is " << box4.volume() << endl;
return 0;
}
自己把程序改成上面这个样子,但是结果还是出错,原因在于程序的调用出现二义性问题,实质是在重复没有没有形参时对象的错误。
因此,上面说的不能重载函数,深层次的理解是同样类型参数的不能重构。其实这样也可以去解释构造函数参数缺省的情况,出现了二义性
构造函数参数缺省值:
参数缺省值只能出现在函数的声明中,而不能出现在定义体中。
例如:
void Foo(int x=0, int y=0); // 正确,缺省值出现在函数的声明中
void Foo(int x=0, int y=0) // 错误,缺省值出现在函数的定义体中 谁见过定义中形参带值的?这样话还需要实参给形参传值吗?
{
…
}
为什么会这样?我想是有两个原因:一是函数的实现(定义)本来就与参数是否有缺省值无关,所以没有必要让缺省值出现在函数的定义体中。二是参数的缺省值可能会改动,显然修改函数的声明比修改函数的定义要方便。
如果函数有多个参数,参数只能从前往后挨个儿缺省,否则将导致函数调用语句怪模怪样。
正确的示例如下:
void Foo(int x, int y=0, int z=0);
错误的示例如下:
void Foo(int x=0, int y, int z=0);
可能产生的二义性:
void output( int x);
void output( int x, float y=0.0);
//output(3);//error,产生二义性