高级程序设计

5 - 构造函数与析构函数

2020-02-27 15:15 CST
2020-03-14 22:29 CST
CC BY-NC 4.0

构造函数

当一个对象被创建时,将会获得一块存储空间,该存储空间用于存储对象的数据成员。在适用对象前,需要对对象存储空间中的数据成员进行初始化。

C++提供了一种对象初始化的机制:构造函数。

  • 它是类的特殊成员函数,名字与类名相同、无返回值类型。
  • 创建对象时,构造函数会被自动调用。

构造函数可以重载,其中不带参数的(或所有参数都有默认值的)构造函数被称为默认构造函数。

在创建对象时:

  • 如果没有指定调用对象类中哪一个构造函数,则调用默认构造函数初始化。
  • 也可以显式地指定调用对象类的某个构造函数。

对象创建后,不能再调用构造函数。

成员初始化表

对于常量和引用数据成员,不能在说明它们时初始化,也不能采用赋值操作在构造函数中对它们初始化。

  • 可以在构造函数的函数头和函数体之间加入一个成员初始化表来对常量和引用数据成员进行初始化。
  • 在成员初始化表中,成员的书写次序并不决定它们的初始化次序,它们的初始化次序由它们在类定义中的描述次序来决定。

析构函数

在类中可以定义一个特殊的成员函数:析构函数,它的名字为~<ClassName>,没有返回类型、不带参数、不能被重载。

一个对象消亡时,系统在收回它的内存空间之前,将会自动调用对象类中的析构函数。可以在析构函数中完成对象被删除前的一些清理工作。

一般情况下,类中不需要自定义析构函数,但如果对象创建后,自己又额外申请了资源,则可以自定义析构函数来归还它们。

析构函数可以显式调用,这时并不是让对象消亡,而是归还对象额外申请的资源。

成员对象的初始化和消亡处理

在创造包含成员对象的对象时,除了会自动调用本身类的构造函数外,还会自动调用成员对象类的构造函数。

  • 通常是自动调用成员对象类的默认构造函数。
  • 如果需要调用非默认构造函数,需要在包含成员对象的对象类的构造函数成员初始化表中显式指出。

包含成员对象的对象消亡时,除了会自动调用本身类的析构函数外,还会自动调用成员对象类的析构函数。

成员对象初始化和消亡处理的次序

创建包含成员对象的对象时:

  • 先执行成员对象类的构造函数,再执行本对象类的构造函数。
  • 若包含多个成员对象,这些成员对象的构造函数执行次序则按它们在本对象类的说明次序进行。

从实现上说:

  • 先调用本身类的构造函数,但在进入函数体之前,会先去调用成员对象类的构造函数,然后再执行本身构造类函数的函数体。
  • 构造函数的成员初始化表(即便没有显式给出)中有对成员对象类的构造函数的调用代码。

注意:如果类中未提供任何构造函数,但它包含成员对象,则编译程序会隐式地为之提供一个默认构造函数,其作用就是调用成员对象类地构造函数。

包含成员对象的对象消亡时:

  • 县知县本身类的析构函数,再执行成员对象类的析构函数。
  • 如果有多个成员对象,则成员对象析构函数的执行次序则按它们再本对象类中的说明次序的逆序进行。

从实现上说:

  • 先调用本身类的析构函数,本身类析构函数的函数体执行完之后,再去调用成员对象类的析构函数。
  • 析构函数的函数体最后又对成员对象类的析构函数的调用代码。

注意:如果类中未提供析构函数,但它包含成员对象,则编译程序会隐式地为之提供一个析构函数,其作用就是调用成员对象类的析构函数。