C++虚析构函数详解
在C++中,当一个基类指针指向派生类对象,通过这个基类指针删除对象时,如果基类的析构函数不是虚函数,会导致派生类的析构函数不被调用,从而引发资源泄漏和不正确的行为。
例如,分析下面的程序:
执行结果为:
在 C++ 中,通过指针访问非虚函数时,编译器会根据指针的类型来确定要调用的函数。示例程序中,ptr 是基类的指针,所以直接调用的是基类的析构函数。
修改上面的程序,将基类的析构函数改为虚析构函数,即用 virtual 修饰析构函数:
例如,分析下面的程序:
#include <iostream> class Base { public: Base() { std::cout << "Base constructor" << std::endl; } ~Base() { std::cout << "Base destructor" << std::endl; } }; class Derived : public Base { public: Derived() { std::cout << "Derived constructor" << std::endl; } ~Derived() { std::cout << "Derived destructor" << std::endl; } }; int main() { Base* ptr = new Derived; delete ptr; return 0; }示例中 Base 类和 Derived 类分别具有构造函数和析构函数。使用 Base 类的指针指向 Derived 类的对象,并使用 delete 关键字删除对象。
执行结果为:
Base constructor
Derived constructor
Base destructor
在 C++ 中,通过指针访问非虚函数时,编译器会根据指针的类型来确定要调用的函数。示例程序中,ptr 是基类的指针,所以直接调用的是基类的析构函数。
修改上面的程序,将基类的析构函数改为虚析构函数,即用 virtual 修饰析构函数:
virtual ~Base() { std::cout << "Base destructor" << std::endl; }注意,设置基类的析构函数为虚函数,则所有派生类的析构函数都自动变为虚函数。再次运行程序:
Base constructor
Derived constructor
Derived destructor
Base destructor