MST

星途 面试题库

面试题:C++中常见的析构函数调用场景有哪些

请详细列举并简要解释C++析构函数在程序运行过程中的常见调用场景,例如对象生命周期结束时等场景。
14.1万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 对象生命周期结束
    • 解释:当一个局部对象(例如在函数内部定义的对象)离开其作用域时,析构函数会被自动调用。这是因为对象在栈上分配,一旦作用域结束,对象不再被需要,系统会释放其占用的资源。例如:
    void func() {
        class MyClass {
        public:
            ~MyClass() {
                // 释放资源相关代码
            }
        };
        MyClass obj;
    } // 当函数执行到这里,obj离开作用域,其析构函数被调用
    
  2. 对象通过delete操作符被释放
    • 解释:如果对象是通过new操作符在堆上动态分配的,当使用delete操作符释放该对象时,析构函数会被调用。这是因为动态分配的对象需要手动释放,delete不仅释放了对象占用的内存,还会调用其析构函数来清理对象内部的资源。例如:
    class MyClass {
    public:
        ~MyClass() {
            // 释放资源相关代码
        }
    };
    int main() {
        MyClass* ptr = new MyClass();
        delete ptr; // 调用MyClass的析构函数,然后释放内存
        return 0;
    }
    
  3. 容器中对象被移除
    • 解释:当从标准模板库(STL)容器(如std::vectorstd::liststd::map等)中移除对象时,该对象的析构函数会被调用。这是因为容器需要清理不再属于它的对象,调用析构函数以释放对象占用的资源。例如:
    #include <vector>
    class MyClass {
    public:
        ~MyClass() {
            // 释放资源相关代码
        }
    };
    int main() {
        std::vector<MyClass> vec;
        vec.push_back(MyClass());
        vec.erase(vec.begin()); // 移除第一个元素,调用MyClass的析构函数
        return 0;
    }
    
  4. 程序正常结束
    • 解释:当程序正常结束(例如main函数执行完毕),全局对象和静态对象的析构函数会被调用。这是为了确保程序在结束前清理所有全局和静态对象占用的资源。例如:
    class MyClass {
    public:
        ~MyClass() {
            // 释放资源相关代码
        }
    };
    MyClass globalObj;
    int main() {
        static MyClass staticObj;
        return 0;
    } // 程序结束时,先调用staticObj的析构函数,再调用globalObj的析构函数
    
  5. 异常抛出导致对象析构
    • 解释:当异常被抛出时,在异常传播路径上所有已经构造但尚未析构的局部对象(自动对象)的析构函数会被调用。这确保了异常处理过程中资源的正确清理,避免内存泄漏等问题。例如:
    class MyClass {
    public:
        ~MyClass() {
            // 释放资源相关代码
        }
    };
    void func() {
        MyClass obj1;
        MyClass obj2;
        throw std::exception(); // 抛出异常,obj1和obj2的析构函数会被调用
    }