MST

星途 面试题库

面试题:C++ 类对象生命周期中的构造函数与析构函数

请简述C++类中构造函数和析构函数的作用,在继承体系下,构造函数和析构函数的调用顺序是怎样的?请举例说明。
40.8万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

构造函数的作用

构造函数是一种特殊的成员函数,与类名相同,没有返回类型(包括 void)。其主要作用是在创建对象时对对象进行初始化,为对象的数据成员分配内存空间并赋予初始值。例如:

class Person {
public:
    std::string name;
    int age;
    Person(const std::string& n, int a) : name(n), age(a) {
        // 这里可以进行更多初始化相关操作
    }
};

在上述代码中,Person 类的构造函数接受两个参数,分别用于初始化 nameage 成员变量。

析构函数的作用

析构函数也是特殊的成员函数,函数名是在类名前加 ~,同样没有返回类型。析构函数在对象生命周期结束时被自动调用,主要用于释放对象在生命周期内分配的资源,比如动态分配的内存等,防止内存泄漏。例如:

class Resource {
private:
    int* data;
public:
    Resource() {
        data = new int[10];
    }
    ~Resource() {
        delete[] data;
    }
};

Resource 类中,构造函数动态分配了一个包含10个 int 类型元素的数组,析构函数负责释放这块内存。

继承体系下构造函数的调用顺序

  1. 调用基类的构造函数:按照继承列表中基类出现的顺序依次调用基类的构造函数。
  2. 调用成员对象的构造函数:按照成员对象在类中声明的顺序调用其构造函数。
  3. 调用自身的构造函数:执行自身构造函数的函数体。

例如:

class Base {
public:
    Base() {
        std::cout << "Base constructor" << std::endl;
    }
};

class Member {
public:
    Member() {
        std::cout << "Member constructor" << std::endl;
    }
};

class Derived : public Base {
private:
    Member member;
public:
    Derived() {
        std::cout << "Derived constructor" << std::endl;
    }
};

当创建 Derived 对象时,输出顺序为:

Base constructor
Member constructor
Derived constructor

继承体系下析构函数的调用顺序

  1. 调用自身的析构函数:执行自身析构函数的函数体。
  2. 调用成员对象的析构函数:按照成员对象在类中声明的逆序调用其析构函数。
  3. 调用基类的析构函数:按照继承列表中基类出现顺序的逆序调用基类的析构函数。

对于上述例子,当 Derived 对象生命周期结束时,输出顺序为:

Derived destructor
Member destructor
Base destructor