虚析构函数

析构函数可以为虚函数,且一般建议为虚函数。

在基类的析构函数为非虚析构函数的情况下:
当通过基类指针来指向派生类所new的对象,如果delete释放该指针的对象,将会只是释放基类的内存,而不会释放派生类的内存,从而导致内存泄漏。因为此时基类的析构函数为非虚析构函数,无法通过动态多态的方式来依次调用 派生类的析构函数基类的析构函数

当基类的析构函数为非虚析构函数时

// 基类
class Base 
{
public:

    virtual void func() {
        printf("Base class\n");
    }

   // 此时基类的析构函数为非虚析构函数,将无法实现动态多态的调用对应的析构函数
    ~Base() {
        printf("Base Destructor.\n");
    }

};

// 派生类
class Derive :public Base
{
public:
    virtual void func() {
        printf("Derive class\n");
    }

    ~Derive() {
        printf("Dervie Destructor.\n");
    }

};

int main()
{
    // 通过基类指针来指向派生类的对象
    Base* p1 = new Derive();

    // 释放该基类指针所指向的对象,将会调用对应的构造函数
    delete p1;

}

运行结果只是调用了基类的析构函数,只是释放了基类的内存,而漏掉了派生类的内存


当基类的析构函数为 虚析构函数时

此时将依次调用:派生类析构函数 ---> 基类析构函数

class Base 
{
public:

    virtual void func() {
        printf("Base class\n");
    }

    // 基类的析构函数为虚析构函数,可以实现动态多态
    virtual ~Base() {
        printf("Base Destructor.\n");
    }

};

class Derive :public Base
{
public:
    virtual void func() {
        printf("Derive class\n");
    }

    virtual ~Derive() {
        printf("Dervie Destructor.\n");
    }

};

int main()
{
    // 通过基类指针来指向派生类的对象
    Base* p1 = new Derive();

    // 释放该基类指针所指向的对象,将会调用对应的构造函数
    delete p1;

}

运行结果如下图:依次释放了 派生类内存和基类内存

posted @ 2023-07-07 15:57  Jeffxue  阅读(19)  评论(0编辑  收藏  举报