美文网首页
C++中基类的析构函数为什么要用virtual虚析构函数?

C++中基类的析构函数为什么要用virtual虚析构函数?

作者: MemetGhini | 来源:发表于2022-05-17 08:33 被阅读0次

析构函数是对象生存期终结时调用的特殊成员函数。析构函数的目的是释放对象可能在它的生存期间获得的资源。

C++中基类采用virtual虚析构函数是为了防止内存泄漏。如果父类的析构函数是非虚的,当删除父类指针指向的子类对象时就不会去调用子类的析构函数,只调用父类的。这时候在子类的资源不能获得释放,发生了内存泄漏,包括成员对象,堆中开辟的内存。

代码实例:

#include <iostream>
using namespace std;

class Base
{
public:
    Base() {
        cout << "🙎父类被构造" << endl;
    };

    ~Base() //Base的析构函数
    {
        cout << "🙎❌父类被析构~" << endl;
    };
    virtual void func()
    {
        cout << "父类方法被调用func" << endl;
    };
};

class Test
{
public:
    Test() {
        cout << "✅成员对象被构造" << endl;
    }

    ~Test() {
        cout << "❌成员对象被析构" << endl;
    }
};

class Derived : public Base
{
public:
    Derived() {
        cout << "👶子类被构造" << endl;
    };

    ~Derived() //Derived的析构函数
    {
        cout << "👶❌子类被析构~" << endl;
    };
    void func() override
    {
        cout << "子类方法被调用func" << endl;
    };
    Test t;
};

int main()
{
    Derived *p1 = new Derived(); //Derived类的指针
    p1->func();
    delete p1;

    cout << "\n<<<<<<<<<<<>>>>>>>>>>>\n" << endl;

    Base *p2 = new Derived(); //Base类的指针
    p2->func();
    delete p2;

    return 0;
}

执行结果:

🙎父类被构造
✅成员对象被构造
👶子类被构造
子类方法被调用func
👶❌子类被析构~
❌成员对象被析构
🙎❌父类被析构~

<<<<<<<<<<<>>>>>>>>>>>

🙎父类被构造
✅成员对象被构造
👶子类被构造
子类方法被调用func
🙎❌父类被析构~

可以看到父类类型的指针指向父类析构函数能够被正常调用,子类类型的指针指向父类子类析构函数没有被调用,成员函数的析构也没有被调用。
如果把基类的析构函数声明为虚函数virtual,并子类override父类的析构函数再来执行。

#include <iostream>
using namespace std;

class Base
{
public:
    Base() {
        cout << "🙎父类被构造" << endl;
    };

    virtual ~Base() //Base的析构函数
    {
        cout << "🙎❌父类被析构~" << endl;
    };
    virtual void func()
    {
        cout << "父类方法被调用func" << endl;
    };
};

class Test
{
public:
    Test() {
        cout << "✅成员对象被构造" << endl;
    }

    ~Test() {
        cout << "❌成员对象被析构" << endl;
    }
};

class Derived : public Base
{
public:
    Derived() {
        cout << "👶子类被构造" << endl;
    };

    ~Derived() override //Derived的析构函数
    {
        cout << "👶❌子类被析构~" << endl;
    };
    void func() override
    {
        cout << "子类方法被调用func" << endl;
    };
    Test t;
};

int main()
{
    Derived *p1 = new Derived(); //Derived类的指针
    p1->func();
    delete p1;

    cout << "\n<<<<<<<<<<<>>>>>>>>>>>\n" << endl;

    Base *p2 = new Derived(); //Base类的指针
    p2->func();
    delete p2;

    return 0;
}

执行结果:

🙎父类被构造
✅成员对象被构造
👶子类被构造
子类方法被调用func
👶❌子类被析构~
❌成员对象被析构
🙎❌父类被析构~

<<<<<<<<<<<>>>>>>>>>>>

🙎父类被构造
✅成员对象被构造
👶子类被构造
子类方法被调用func
👶❌子类被析构~
❌成员对象被析构
🙎❌父类被析构~

很明显下面这种才是符合预期的,父类子类都被析构了。

相关文章

  • ★03.关于单继承

    基类总是要写虚析构函数 通过设置析构函数为纯虚函数来让类称为抽象基类 代码 函数virtual属性的传递性 拷贝移...

  • C++总结

    函数 为什么基类的析构函数用虚函数 在实现多态时,当用基类操作派用类,在析构时防止只析构基类而不析构派生类的状况发...

  • 2020-02-10 C++基础2

    1:为什么析构函数必须是虚函数?为什么C++默认的析构函数不是虚函数? 将可能会被继承的父类的析构函数设置为虚...

  • c++primer 15.24-15.30

    15.24基类一般定义一个虚析构函数但是虚析构函数会阻止移动操作但是虚析构函数会帮助基类派生类体系动态销毁对象15...

  • 如何写C++基类析构函数?

    可以看到,派生类的析构函数没有被调到。解决方法是,在基类的析构函数前加virtual。

  • 警告:deleting object of polymorphi

    原来如果基类里有虚函数,定义了基类指针指向派生类,就会需要定义基类虚析构,这样,基类指针析构的时候,就会先析构派生...

  • GeekBand C++面向对象高级编程(下)(第四周):没有虚

    在C++中,如果一个类是作为父类存在时,那么析构函数必须是虚析构函数,否则在对其子类进行析构时,只会释放其父类的成...

  • 简介python中的析构函数与构造函数

    python的构造和析构函数为固定的名字。 构造函数 析构函数 不像c++中那样构造函数和析构函数是类名字。并且在...

  • C++虚函数的一些奇怪问题总结

    构造函数能否为虚函数?在构造函数中调用虚函数会如何?析构函数能否为虚函数?析构函数能否为纯虚函数?其实日常开发中基...

  • C++中基类的析构函数为什么要用virtual虚析构函数(转)

    只要是基类,就要将析构函数设置为虚函数,否则,当将基类指针指向子类的对象时,delete基类指针不会调用子类的析构...

网友评论

      本文标题:C++中基类的析构函数为什么要用virtual虚析构函数?

      本文链接:https://www.haomeiwen.com/subject/dkgourtx.html