4.构造函数
构造函数主要用于在定义对象时,完成对象的初始化.
每一个类都应该有一个构造函数,如果用户没有定义构造函数,编译器会自动生成构造函数(参数和函数体为空的构造函数),如果用户自定义了构造函数,那么编译器不再提供默认的构造函数。
特性:1.构造函数的名称必须要与当前类的名称相同。
2.构造函数仅在定义对象时由系统调用,其他时间无法调用。而且只执行一次。
3.构造函数可以有参数,也可以没有参数,但是不允许有返回值。
4.构造函数只能定义为公有成员,不能定义为其他。
调用条件:1.定义对象时。2.为对象分配动态内存时。3.定义无名对象(稍作了解)
注意:(1)构造函数可以进行重载,以便用于不同形式的对象的定义。(2)构造函数还可以使用默认的缺省参数。如果构造函数既有重载,又有缺省参数时,注意不要产生二义性。
参数初始化表:
除了构造函数进行对成员数据进行初始化,还有参数初始化表对数据初始化,在函数首部实现。
例如:BOX::BOX(int h,int w,int len):height(h),width(w),length(len){}
类名::构造函数名([参数表])[:成员初始化表]
{[构造函数体]}
如果数据成员是数组,则需要在构造函数的函数体内用语句对其复制,不能再参数初始化表中进行对其初始化。
构造函数的重载:
在一个类中定义多个构造函数名具有相同的名字,而参数的个数或者参数的类型不同。
5.析构函数
析构函数是一种特殊的成员函数,完成与构造函数相反的工作,对象退出生命周期时,完成清理的工作。如:释放内存等。
特性:
1.析构函数的名称与类的名称相同。为了区分,析构函数名字前面有~
构造:stu(){} 析构:~stu(){}
2.析构函数无参、无返回值。
3.析构函数不可重载。每一个类有且只有一个析构函数,但是可以有多个构造函数。
4.在对象退出生命周期时,编译器会自动调用析构函数。但是,可以人为调用析构函数,不过没意义。
5.一般情况下,使用系统默认的析构函数就可以。当类中有动态内存分配时,需要增加自定义的析构函数,否则有可能会导致内存泄露。
调用条件:
1.对象退出生命周期时。定义的对象在调用结束后释放时自动执行析构函数。
2.释放动态分配的对象空间。使用new运算符动态的建立了一个对象,当使用delete运算符释放该对象时, 先调用该对象的析构函数。
3.定义的全局的对象在程序离开其作用域的时候调用该全局对象的析构函数。
4.静态(static)局部对象在程序调用结束时对象并不释放,因此也不调用析构函数,只在main函数结束或调用exit函数结束程序时,才调用static局部对象的析构函数。
6.析构顺序
同一作用域下,先构造的后析构。即最先被调用构造函数,其对应的析构函数最后被调用。先进后出。
调用析构函数的顺序与存储类别有关。
7.拷贝构造函数
在定义对象时,使用已知对象初始化新的对象。
特性:
1、拷贝构造函数也是构造函数,名称为类的名字,无返回值。
2、如果没有自定义的拷贝构造函数,系统会提供默认的拷贝构造函数
stu(const 当前类的对象的引用)
{
}
当类中有指针且进行动态内存分配时,要使用自定义的拷贝构造函数。
3、可以自定拷贝构造函数,如果自定义后,默认的拷贝构造函数失效。
补充:
浅拷贝:只复制数据,没复制内存空间。
深拷贝:既拷贝数据,也要复制内存空间。
调用条件:
1、使用已知对象初始化新对象。
stu s2 = s1;
2、如果函数参数是某类的对象
void fun(stu s1){}
fun(s2);
3、如果函数返回值为某类的对象时。
stu fun(){}
stu s1 = fun();
如果使用无名对象初始化新的对象,不会调用拷贝构造函数。
8. this指针:
指向本类对象的指针,它的值是当前被调用的成员函数所在的对象的起始地址。This指针是隐式使用的,它是作为参数被传递给成员函数的。
9. 常对象:
类名 const 对象名[(实参表)] 或者 Const 类名 对象名[(实参表)]
在定义的时候必须初始化,如果一个对象声明为常对象,只能调用该对象的常成员函数,而不能调用其他的一般成员函数。常成员函数是常对象的唯一对外接口。常成员函数可以访问常对象中的数据成员,但是不允许修改对象中数据的值。但是一般的成员函数可以引用类中的非const数据成员也可以改变他们。
10. 常对象成员
常对象的数据成员都是常数据成员,必须通过构造函数的参数初始化表对常数据成员进行初始化。
Const int hour;
Time::Time(int h):hour(h){}
常成员函数:可以访问常对象中的数据成员,但是不允许修改对象中数据的值。
类型名 函数名(参数表) const;
11. 指向常对象的指针变量
Const 类型名 * 指针变量名
如果一个变量声明为常变量,只能用指向常变量的指针向量指向它。
指向常变量的指针变量除了可以指向常变量外,也可以指向未被声明为const的变量,但是不可通过该指针变量改变变量的值。
当希望在调用函数时,对象的值不被修改,就应当把形参定义为指向常变量的指针变量,同时用对象的地址作为实参(对象可以是const或者非const型的)如果要求该对象不仅在调用函数的时候不被改变,而且要求它在程序执行的过程都不被调用,则需要把对象也定义为const型。
Time const t; t是一个常对象,其值在任何情况下都不能改变。
Void Time::fun() const; fun是Time类中的常成员函数,可以引用,但是不能改变本类中的数据成员。
Time *const p; p是指向Time类对象的常指针变量,p的值不能改变。
Const Time *p; p是指向Time类对象的指针变量,P指向的类对象的值不可以通过p来改变。
Const Time &t1=t; t1是Time 类对象t的引用,二者指向同一个存储空间,t的值不能改变。