|
|
|
(1)是成员函数的一种,名字与类名相同,可以有参数,不能有返回值(void也不行)。
|
|
|
(2)其作用是对对象进行初始化,如给成员变量赋初值。
|
|
|
(3)如果定义类时没写构造函数,则编译器生成一个默认的无参数的构造函数。默认构造函数无参数,什么也不做。默认的构造函数也可以由程序员自己来编写,只要构造函数是无参的或者只要各参数均有默认值,C++编译器都认为是默认的构造函数,并且默认的构造函数只能有一个。
|
|
|
(4)如果定义了构造函数,则编译器不生成默认的无参数的构造函数。
|
|
|
|
(6)一个类可以有多个构造函数,它们的参数个数或类型不同,构成函数重载。
|
|
|
构造函数一般声明为public,当然有时为了特殊需要也可定义为private。
|
|
|
|
同一个类的对象在内存中有完全相同的结构,如果作为一个整体进行复制是完全可行的。这个复制过程只需要复制数据成员,而函数成员是共用的(只有一份副本)。
|
|
|
在建立对象时可用同一类的另一个对象来初始化该对象,这时所用的构造函数称为复制初始化构造函数(CopyConstructor)。形如X::X(X&),只有一个参数——同类(Class)的对象,采用的是引用的方式。不允许有形如X::X(X)的构造函数,如果把一个真实的类对象作为参数传递到复制构造函数,会引起无穷递归。如果没有定义,那么编译器生成默认复制构造函数。如果定义了自己的复制构造函数,则默认的复制构造函数不存在。
|
|
|
|
|
|
(2)如果某函数有一个形参是类A的对象,那么该函数被调用时,类A的复制构造函数将被调用。
|
|
|
|
(3)如果函数的返回值是类A的对象,则函数返回时,A的复制构造函数被调用。理由也是要建立一个临时对象,再返回调用者。
|
|
|
|
为什么不直接用要返回的局部对象呢?因为局部对象在离开建立它的函数时就消亡了,不可能在返回调用函数后继续生存。所以编译系统会在调用函数的表达式中创建一个无名临时对象,该临时对象的生存周期只在函数调用处的表达式中。所谓return对象,实际上是调用复制构造函数把该对象的值复制到临时对象。
|
|
|
|
当一个对象定义时,C++自动调用构造函数建立该对象并进行初始化,那么当一个对象的生命周期结束时,C++也会自动调用一个函数注销该对象并进行善后工作,这个特殊的成员函数即析构函数(Destructor)。
|
|
|
(1)析构函数名也与类名相同,但在前面加上字符"~",如~CGoods()。
|
|
|
(2)析构函数无函数返回类型,在这方面与构造函数是一样的,但析构函数不带任何参数。
|
|
|
(3)一个类有一个也只有一个析构函数,这与构造函数不同。析构函数可以缺省。
|
|
|
|
|
对于不同作用域的对象类型,构造函数和析构函数的调用如下。
|
|
|
(1)对于全局定义的对象,当程序进入入口函数main之前对象就已经定义,这时要调用构造函数。整个程序结束时,调用析构函数。
|
|
|
(2)对于局部定义的对象,每当程序控制流到达该对象定义处时,调用构造函数。当程序控制流走出该局部域时,调用析构函数。
|
|
|
(3)对于静态局部定义的对象,在程序控制流首次到达该对象定义处时,调用构造函数。当整个程序结束时,调用析构函数。
|
|
|
|
有成员对象的类称为封闭(Enclosing)类。对成员对象初始化,必须调用该成员对象的构造函数来实现。先调用所有对象成员的构造函数,然后才调用封闭类的构造函数。对象成员的构造函数调用次序和对象成员在类中的说明次序一致,与它们在成员初始化列表中出现的次序无关。当封闭类的对象消亡时,先调用封闭类的析构函数,然后再调用成员对象的析构函数,次序和构造函数的调用次序相反。
|
|
|
|
|