MST

星途 面试题库

面试题:C++中析构函数设为虚拟对资源释放有何意义

在C++中,当我们把析构函数声明为虚拟的,它对资源释放起到怎样的保障作用?请结合具体代码示例说明。
48.4万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

在C++中,将析构函数声明为虚拟的主要作用是确保在通过基类指针删除派生类对象时,能够正确调用派生类的析构函数,从而保证资源的正确释放。

以下是具体代码示例:

#include <iostream>

class Base {
public:
    Base() {
        std::cout << "Base constructor" << std::endl;
    }
    // 如果这里不声明为virtual,派生类的析构函数不会被调用
    virtual ~Base() {
        std::cout << "Base destructor" << std::endl;
    }
};

class Derived : public Base {
public:
    Derived() {
        std::cout << "Derived constructor" << std::endl;
        data = new int(42);
    }
    ~Derived() {
        std::cout << "Derived destructor" << std::endl;
        delete data;
    }
private:
    int* data;
};

int main() {
    Base* ptr = new Derived();
    delete ptr; // 如果Base的析构函数不是虚拟的,这里只会调用Base的析构函数,而不会调用Derived的析构函数,导致内存泄漏
    return 0;
}

在上述代码中:

  1. Base类是基类,Derived类是从Base类派生而来。
  2. Derived类在构造函数中分配了动态内存(new int(42)),并在析构函数中释放(delete data)。
  3. 如果Base类的析构函数不是虚拟的,当通过Base*指针删除Derived类对象时(delete ptr;),只会调用Base类的析构函数,而不会调用Derived类的析构函数,这样Derived类中分配的内存就无法释放,导致内存泄漏。
  4. 当将Base类的析构函数声明为虚拟的后,通过Base*指针删除Derived类对象时,会先调用Derived类的析构函数,释放Derived类中分配的资源,然后再调用Base类的析构函数,确保资源得到正确释放。