一、构造函数
C++中结构struct可以用花括号的方式进行初始化,但是类不行,原因在于数据部分的访问状态是私有的,程序不能直接访问数据成员,而若设置为公有又违反数据隐藏的原则。程序只能通过成员函数访问数据成员。
为此,提供了特殊的成员函数——构造函数,其名称与类名相同。其原型和函数头有一个有趣的特征:虽然没有返回值,但没有被声明为void类型。实际上,它没有声明类型。每次创建类对象(甚至使用new分配内存)时,将自动调用构造函数。
在声明的时候,可以设置默认的参数:
Stock ( const string & co, long n = 0, double PR = 0.0 );
复习:若给某一参数设置了默认值,那么在其后所有参数都必须也设置默认值;调用时,若给已经设置默认值的参数传递实际值,即要取代默认值,则在参数表中被取代参数的左边所定义的所有参数,无论是否有默认值,都必须传递实际参数,即调用都是从左到右匹配参数。
注意构造函数的参数名不能与类成员相同,否则代码会出现形如:
shares = shares;
一般,我们会在数据成员名中加入前缀m_,或者加后缀_。
当且仅当类声明中没有提供任何构造函数时,C++才自动提供默认构造函数,不做任何工作,可能形如:
Stock::Stock(){ }
此时,各个成员的值是随机的不确定的,就和int x;一样的结果。
如果为类定义了构造函数后,就必须为它提供一个不接受任何参数的默认构造函数。有两种方法,一种是给已有的构造函数的所有参数提供默认值:
Stock ( const string & co = "Error" , long n = 0, double pr = 0.0 );
另一种方法是通过函数重载定义另一个构造函数:
Stock();
由于只能有一个默认构造函数,因此不要同时使用这两种方式。有了默认构造函数后,就可以声明对象变量而不对它们进行显式初始化。
补充:对于非静态的const数据成员以及引用数据成员,其必须使用成员初始化列表进行初始化,因为其只能在对象创建时进行初始化,即创建对象时执行构造函数体之前进行初始化。
语法:
Classy::Classy(int n, int m) : mem1(n),mem2(0),mem3(n*m + 2)
{
//..
}
其中,mem1、mem2和mem3是Classy类的数据成员。而对于简单数据成员而言,使用成员初始化列表和在构造函数体中使用赋值没什么区别。但如果本身就是类对象的成员,使用成员初始化列表效率更高。
二、析构函数
对象过期时,将自动调用析构函数,完成清理工作。其名称为类名前加~。和构造函数一样,析构函数没有返回值和声明类型,没有参数,形如:
~Stock();
调用的时机:如果创建的是静态存储类对象,则在程序结束时自动被调用;如果创建的是自动存储类对象,则在程序执行完定义所在的代码{}块后自动调用;如果对象时通过new创建的,则它将主流在占内存或自由存储区中,当使用delete释放内存时,自动调用析构函数。
必需有一个析构函数。如果没有提供,编译器将声明一个默认析构函数。
新闻热点
疑难解答