构造函数、析构函数

构造函数

首先介绍为什么会有构造函数呢,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 //----函数定义

你可能感兴趣的:(c++)