父类析构函数一定要使用析构函数的原因

hacker_dvd / 2023-05-11 / 原文

如果基类的析构函数不是虚函数,在删除一个指向派生类对象的基类指针时,只有基类的析构函数被调用,而派生类的析构函数不会被调用。这可能导致资源泄漏,未正确释放派生类分配的内存等问题。

当基类的析构函数被声明为虚函数时,C++运行时会根据实际的对象类型调用相应的析构函数。这意味着当删除指向派生类对象的基类指针时,先调用派生类的析构函数,然后调用基类的析构函数,确保资源被正确释放。

举个例子:

#include <iostream>

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

    // 如果不将此处的析构函数声明为虚函数,会导致未正确释放派生类资源的问题
    virtual ~Base() {
        std::cout << "Base destructor" << std::endl;
    }
};

class Derived : public Base {
public:
    Derived() : data(new int[10]) {
        std::cout << "Derived constructor" << std::endl;
    }

    ~Derived() {
        std::cout << "Derived destructor" << std::endl;
        delete[] data;
    }

private:
    int *data;
};

int main() {
    Base *basePtr = new Derived();
    delete basePtr; // 如果基类析构函数为虚函数,则会正确调用派生类的析构函数,然后调用基类的析构函数
}

在这个例子中,如果基类的析构函数不是虚函数,删除指向Derived对象的Base指针时,只会调用Base的析构函数,而Derived的析构函数不会被调用。这将导致Derived类中分配的内存(data成员)未被释放,造成内存泄漏。

因此,当使用基类指针处理派生类对象时,通常建议将基类的析构函数声明为虚函数,以确保资源被正确释放。