构造函数
首先介绍为什么会有构造函数呢,c++的目标之一是让使用类对象就像使用标准类型一样,但是如果没有构造函数,目前还是无法实现的。
int a=10;//int类型初始化
struct student
{
int id;
int grade;
};
student stu={1,80};//结构体变量初始化
class Student
{
int id;//默认私有
int grade;
};
Student stu1={2,90}; // 类对象初始化 不允许!!!
为什么不能这样初始化Student对象呢?
因为数据访问对象是私有的,因此不能直接访问数据成员。因此只有通过成员函数来访问数据成员,要设计合适的成员函数才能成功地将对象初始化。
C++提供了一个特殊地成员函数----构造函数,专门用于构造新对象,将值对它进行初始化。
更准确地说,C++为这些成员函数提供了名称和使用语法,而程序员需要提供方法定义。
例如,Student类一个可能的构造函数是名为Student()的成员函数。并且构造函数没有声明类型,没有返回值,同时也没声明为void类型。
声明和定义构造函数
现在我们需要创建Student的构造函数。由于需要为Stu对象提供2个值,因此应为构造函数提供2个参数。有时程序可能只想设置学号一个成员,而把其他设置为0,可以使用默认参数来完成,原型如下:
Student (int i=0, int gd=0) ;//带有默认参数的构造函数原型
注意:没有返回类型,也没有void ; 原型位于类声明的共有部分。
下面是构造函数的一种可能定义:
Student::Student(int i , int gd)
{
id=i;
grade=gd;
}
使用构造函数
C++使用两种使用构造函数来初始化对象的方式。第一种是显式地调用构造函数,另一种是隐式地调用。
Student stu1=Student(1,12);
这将stu1对象的id成员设置为1,grade成员设置为12。
Student Stu1(1,12);
这种格式更加紧凑,它与上面的显式调用是等价的。
构造函数的使用方法不同于其他类方法。构造函数无法使用对象来调用构造函数,因为在构造函数造出对象之前,对象是不存在的。因此,构造函数是用来创建对象的,而不能通过对象来调用。
默认构造函数
默认构造函数用于以下声明的构造函数。
Student stu2;//没有提供初始值
提醒:如果没有任何构造函数,那么C++会自动提供默认构造函数。它不做任何工作。它可能是这样:
Student::Student ()
{}
因此将创建stu2对象,但不初始化其成员。
注意:如果程序员为类定义了构造函数,那么必须为它提供默认构造函数。否则的话,以后的声明会报错:
Student stu3;//报错
定义默认构造函数方式也有两种。一种是给已有构造函数的所有函数提供默认值。另一种是通过函数重载来定义另一个构造函数----一个没有参数的构造函数。
Student (int i=0, int gd=0) ;//带有默认参数的构造函数原型
Student();
不管使用上述哪一种方式创建默认构造函数,都可以声明类对象而不对它们进行初始化,例如:
Student stu1;
Student stu1=Student ();
注意:隐式地调用默认构造函数时,不要使用圆括号。
析构函数
用构造函数创建对象后,程序负责跟踪对象。直到其过期位置,当对象过期时,程序将自动调用析构函数。析构函数负责清理工作。
如果构造函数使用new来分配内存,则析构函数将使用delete来释放这些内存。
如果没有使用new,那么析构函数实际上没有需要完成地任务。这种情况下,只需要让编译器生成一个什么都不用做地隐式析构函数。
析构函数地名称:在类名之前加上~。
比如,Student类的析构函数是~Student()。 而且,析构函数也同样没有返回值和声明类型。与构造函数不同的是,析构函数没有参数。
由于在类对象过期时,析构函数必须将自动被调用,因此必须有一个析构函数。如果程序员没有提供析构函数,编译器会自动隐式地声明一个默认析构函数。
const成员函数
将const关键字放在函数的括号后面,可以保证函数不会被修改。例如:
void show() const;//确保函数不会被修改----函数原型
Student::void show() const //----函数定义