用构造函数实现数据成员的初始化
用户自己定义构造函数示例:
class Time //声明Time类
{
public:
Time() //定义构造成员函数,函数名与类名相同
{
hour=0;
minute=0;
sec=0;
}
void set_time(); //成员函数声明
void show_time(); //成员函数声明
private:
int hour;
int minute;
int sec;
};
构造函数的名字必须与类名同名,不能任意命名。
示例中,根据构造函数Time的定义,其作用是对该对象中的全部数据成员赋以初值0。
也可以在类内进行声明而在类外定义构造函数:
//在类内写这么一句
Time(); //对构造函数进行声明
//在类外定义构造函数
Time::Time() //在类外定义构造成员函数,要加上类名Time和域限定符"::"
{hour=0;
minute=0;
sec=0;
}
关于构造函数使用的说明:
1、在建立类对象时会自动调用构造函数。在建立对象时系统为该对象分配储存单元,此时执行构造函数,就把指定的初值送到有关数据成员的储存单元中。每建立一个对象,就调用一次构造函数。
2、构造函数没有返回值,它的作用只是对对象进行初始化,因此也不需要在定义构造函数时声明类型。
3、构造函数不需要用户使用,亦不能被用户调用。
4、可以用一个类对象初始化另一个类对象,如
Time t1; //建立对象t1,同时调用构造函数t1.Time()
Time t2=t1; //建立对象t2,并用t1初始化t2
此时,把对象t1的各数据成员的值复制到t2相应各成员,而不调用构造函数t2.Time()。
5、在构造函数的函数体中不仅可以对数据成员赋初值,而且可以包含其他语句,例如cout语句(但不建议)。
6、如果用户没有定义构造函数,C++系统会自动生成一个构造函数,只是这个构造函数函数体是空的,也没有参数,不执行初始化操作。
用带参数的构造函数对不同对象初始化
观察以下代码:
#include <iostream>
using namespace std;
class Box //声明Box类
{
public:
Box(int, int, int); //声明带参数的构造函数
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(12, 25, 30); //建立对象box1,并指定box1的高、宽、长的值
cout << "The volume of box1 is " << box1.volume() << endl;
Box box2(15, 30, 21); //类似上
cout << "The volume of box2 is " << box2.volume() << endl;
return 0;
}
可以采用带参数的构造函数,在调用不同对象的构造函数时,从外面将不同的数据传递给构造函数,以实现对不同对象的初始化。构造函数首部的一般格式为
类名 对象名 (类型1 形参1,类型2 形参2,...)
实参是在定义对象时给出的。定义对象的一般格式为
类名 对象名 (实参1,实参2,...)
在建立对象时把实参的值传递给构造函数相应的形参,把它们作为数据成员的初值。
参数初始化表
对上方代码中定义构造函数可以改用以下形式:
Box::Box(int h,int w,int len):height(h),width(w),length(len){}
即在原来函数首部的末尾加一个冒号,然后列出参数的初始化表。
对构造函数进行重载
看代码看代码:
#include <iostream>
using namespace std;
class Box
{
public:
Box(); //声明一个无参的构造函数Box
Box(int h, int w, int len) :heigth(h), width(w), length(len){}
//定义一个有参的构造函数,用参数的初始化表对数据成员初始化
int volume(); //声明成员函数volume,用于计算体积
private:
int heigth;
int width;
int length;
};
Box::Box() //在类外定义无参构造函数Box
{
heigth = 10;
width = 10;
length = 10;
}
int Box::volume() //在类外定义成员函数volume
{
return(heigth * width * length);
}
int main()
{
Box box1; //建立对象box1,不指定实参
cout << "The volume of box1 is " << box1.volume() << endl;
Box box2(15, 30, 25); //建立对象box2,指定3个实参
cout << "The volume of box2 is " << box2.volume() << endl;
return 0;
}
本程序中定义了两个同名的构造参数,其实还可以定义更多的重载构造函数。例如还可以有以下的构造函数原型:
Box::Box(int h); //有一个参数的构造函数
Box::Box(int h,int w); //有两个参数的构造函数
在建立对象时可以给出一个参数和两个参数,系统会分别调用相应的构造函数。
ps.一个类中可以包含多个构造函数,但是对于每一个对象来说,建立对象时只执行其中一个构造函数。
在构造函数中使用默认参数
意思就是说如果你不给人家指定初始值人家有自己的默认初始值。
上代码:
#include <iostream>
using namespace std;
class Box
{
public:
Box(int h = 10, int w = 10, int len = 10); //在声明构造函数Box时指定默认参数
int volume();
private:
int heigth;
int width;
int length;
};
Box::Box(int h,int w,int len) //在定义Box函数时可以不指定默认参数
{
heigth = h;
width = w;
length = len;
}
int Box::volume()
{
return(heigth * 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); //只给定两个实参
cout << "The volume of box3 is " << box3.volume() << endl;
Box box4(15,30,20); //给定三个实参
cout << "The volume of box4 is " << box4.volume() << endl;
return 0;
}
这是在上方代码的基础上改写的。可以看到,在构造函数中使用默认参数是方便有效的,它提供了建立对象时的多种选择,其作用相当于好几个重载的构造函数。好处多多,即使在调用构造函数时没有提供实参值,不仅不会出错,而且还确保按照默认的参数值对对象进行初始化。尤其在希望每一个对象都有同样的初始化状况时用这种方法更为方便,无须输入数据,对象全按事先指定的值进行初始化。
一些说明:
1、应该在声明构造函数的时候就指定默认值。
2、在声明构造函数时,形参名可以省略,如
Box(int=10,int=10,int=10);
3、如果同时定义了下面两个构造函数,是错误的
Box(); //声明一个无参的构造函数
Box(int=10,int=10,int=10); //声明一个全部参数都指定了默认值的构造函数
在建立对象时,如果写成
Box box1;
系统会不知道该用哪个构造函数,会报错。
4、在一个类中定义了全部是默认参数的构造函数后,不能再定义重载构造函数。
还是那个原因,系统会不知所措(划掉),不知道该选哪个,然后报错无法运行。
总结:用构造函数实现初始化方法的归纳
1、在类中定义构造函数的函数体中对数据进行赋初值。
public:
Time()
{
hour=0;
minute=0;
sec=0;
}
在建立对象时执行构造函数,给数据赋初值。如果定义了多个对象,每个对象中的数据的初值都是相同的(为0)。
2、用带参数的构造函数,可以使同类的不同对象中的数据具有不同的初值。
Box(int h,int w,int len)
{
heigth=h;
width=w;
length=len;
}
在定义对象时指定实参。
Box box1(12,25,30);
把12,25,30传递给构造函数的形参,再赋给对象中各数据。不同的对象可以有不同的初值。
3、在构造函数中用参数初始化表实现对数据赋初值。
Box(int h,int w,int len):height(h),width(w),length(len){};
作用与2中的相同,但免去了2中定义的函数体,使构造函数简单精炼,使用方便。定义对象的形式与2中的相同。
Box box1(12,25,30);
4、在定义构造函数时可以使用默认参数。
Box(int h = 10, int w = 10, int len = 10)
{
height=h;
width=w;
length=len;
}
上面的构造函数可以改用参数初始化表如下:
Box(int h=10,int w=10,int len=10):height(h),width(w),length(len){};
这样更为简洁方便。
在定义对象时,如果不指定实参,则以默认参数作为初值(例子在上面)。
5、重载重载(也在上面)。
一定要注意就是一般不同时使用有默认参数的构造函数和构造函数的重载,系统会短路。
就到这里啦!