关于类和对象的进一步讨论 C++
如果一个类中所有成员函数都是公用的,则可以在定义对象时对数据成员进行初始化:
class Time
{
public:
hour;
minute;
sec;
};
Time t1={14,15,23};//将t1初始化为14:15:23
但是数据成员是私有的,或者类中有private或protected的成员,就不能用这种方法初始化。
构造函数:
构造函数是一种特殊的成员函数,用来处理对象的初始化,它不需要用户调用它,而是在建立对象时自动执行。构造函数的名子必须与类名同名,而不能由用户任 意命名,以便编译系统能够识别它并把它作为构造函数处理。它不具有任何类型,不返回任何值。构造函数的功能是由用户定义的,用户根据初始化的要求设计函数和函数参数。
#include <iostream>
using namespace std;
class Time
{
public:
Time()
{
hour=0;
minute=0;
sec=0;
}
void set_time();
void show_time();
private:
int hour;
int minute;
int sec;
};
void Time::set_time()
{
cin>>hour;
cin>>minute;
cin>>sec;
}
void Time::show_time()
{
cout<<hour<<":"<<minute<<":"<<sec<<endl;
}
int main()
{
Time t1,t2;
t1.set_time();
t1.show_time();
t2.set_time();
t2.show_time();
return 0;
}
在Time中定义了构造函数Time,它和所在的类同名,在建立对象时自动执行构造函数,它的作用是对该对象中的各数据成员赋初值0。记住,不要认为在声明时直接对程序数据成员赋初值。,这是错的,赋值语句只能写在构造函数体中,只有在调用构造函数时才执行这些赋值语句,对当前的对象中的数据成员赋值。
上面是在类内定义构造函数,也可以只在类内对构造函数进行声明而在类外定义构造函数。如
Time();
在类外定义构造函数:
Time::Time()
{
hour=0;
minute=0;
sec=0;
}
有关构造函数的说明:
1.什么时候开始使用构造函数?在类对象进入其作用域时开始调用构造函数。
2.构造函数没有返回值,因此也不需要在定义构造函数时声明类型,这是它和一般函数的一个重要的不同点。
3.构造函数不需要用户调用,也不需要被用户调用。构造函数在建立对象时由系统自动执行的,而且只执行一次。构造函数一般声明为public。
4.在构造函数的函数体中不仅可以对数据成员赋初值,而且可以包含其他语句,例如cout语句。但是一般不提倡在构造函数中加入与初始化无关的内容,以保 持程序的清晰。
5.如果用户自己没有定义构造函数,则C++系统会自动生成一个构造函数,只是这个构造函数的函数体是空的,也咩有参数,不执行初始化的操作。
带参数的构造函数。
由于有时用户需要对不同的对象赋予不同的初值,这时就就无法使用不含参数的构造函数实现了。
可以使用带参数的构造函数,在调用不同对象的构造函数时,从外面将不同的数据传递给构造函数,以实现不同的初始化,构造函数的一般格式:
构造函数名(类型1 形参1,类型2 形参2,类型3 形参3,....)
用户是不能调用构造函数的,因此无法采用常规的调用函数的方法给出实参(如fun(a,b)),实参是在定义对象时给出的,定义对象的一般格式为:
类名 对象名(实参名1,实参名2,....)
记住:带形参的构造函数主要目的就是为了使用不同的参数来得到不同的结果。实现对不同的对象进行不同的初始化。
使用参数初始化表对数据成员初始化
参数初始化表来实现对数据成员的初始化,这种方法不在函数体内对数据成员初始化,而是在函数首部实现。例如:
Box::Box(int h,int w,int len):height(h),width(w),length(len){}
即在原来函数首部的末尾加一个冒号,然后列出参数的初始化表。上面的初始化表表示:用形参h的值初始化数据成员height,用形参w初始化数据成员 width,用形参len的值初始化数据成员length。甚至可以直接在类体中定义函数。
构造函数的重载。
在一个类中可以定义多个构造函数,以便对类对象提供不同的初始化的方法,供用户选用。这些构造函数具有相同的名字,而参数的个数或参数的类型不相 同。这称为构造函数的重载。
说明:
1.调用构造函数时不必给出实参的构造函数,称为默认构造函数,有些书中翻译为缺省构造函数。显然,无参数的构造函数属于默认的构造函数。一个类 中只可以有一个默认的构造函数。
2.如果在建立对象时选用的是无参数构造函数,应该注意正确书写定义对象的语句。
3.尽管在一个类中可以包含多个构造函数,但是对于每一个对象来说,建立对象时只执行其中的一个构造函数,并非每个构造函数都被执行。
使用默认的构造函数。
构造函数中参数的值既可以通过实参传递,也可以指定为某些默认值,即如果用户不指定实参值,编译系统就使形参去默认值。
#include <iostream>
using namespace std;
class Box
{
public:
Box(int h=10,int w=10,int len=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);
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.如果构造函数的全部参数都指定了默认值,则在定义对象时可以给出一个或几个实参,也可以不给出实参。
3.在一个类中定义了全部是默认参数的构造函数后,不能在定义重载构造函数。