MST

星途 面试题库

面试题:C++ 虚析构函数在复杂继承体系下对资源释放的影响

假设有一个多层继承的 C++ 类体系,基类有动态分配的资源。在这种情况下,如果析构函数未声明为虚函数,会出现什么问题?详细说明虚析构函数在这种复杂继承体系中是如何保障每一层的资源都能正确释放的,同时请给出代码示例进行分析。
28.4万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 未声明虚析构函数的问题
    • 当析构函数未声明为虚函数时,如果通过基类指针删除派生类对象,只会调用基类的析构函数,而不会调用派生类的析构函数。这会导致派生类中动态分配的资源无法释放,从而产生内存泄漏。
  2. 虚析构函数保障资源正确释放的原理
    • 虚析构函数利用C++的多态机制。当使用基类指针删除对象时,根据对象的实际类型(运行时类型),会调用相应的析构函数。在多层继承体系中,从最派生类的析构函数开始调用,然后依次调用其直接基类的析构函数,直到调用到基类的析构函数,这样就能保证每一层动态分配的资源都能被正确释放。
  3. 代码示例
#include <iostream>
#include <cstring>

class Base {
public:
    Base() {
        data = new char[10];
        std::strcpy(data, "Base");
    }
    // 非虚析构函数(错误示例)
    // ~Base() {
    //     delete[] data;
    // }
    // 虚析构函数(正确示例)
    virtual ~Base() {
        delete[] data;
    }
private:
    char* data;
};

class Derived : public Base {
public:
    Derived() {
        moreData = new char[10];
        std::strcpy(moreData, "Derived");
    }
    ~Derived() {
        delete[] moreData;
    }
private:
    char* moreData;
};

int main() {
    Base* ptr = new Derived();
    delete ptr;
    return 0;
}

在上述代码中,如果Base类的析构函数不是虚函数,当delete ptr执行时,只会调用Base类的析构函数,Derived类中moreData所指向的内存不会被释放。而将Base类的析构函数声明为虚函数后,delete ptr会先调用Derived类的析构函数,释放moreData,然后再调用Base类的析构函数,释放data,从而避免内存泄漏。