【C++】虚析构和纯虚析构

在C++中,使用虚函数和纯虚函数实现多态,但需注意子类对象在堆区分配时,若含有堆内存,需确保父类有虚析构函数,以防止内存泄漏。无虚析构时,删除父类指针不会调用子类析构。文章强调了虚析构函数在管理含有动态内存子类对象时的重要性。
摘要由CSDN通过智能技术生成

在C++的多态中,为了晚绑定提出了虚函数和纯虚函数,利用父类指针管理子类对象来实现多态

由于子类对象在堆区开辟,在程序结束前需要手动管理父类指针,但是如果子类属性中有在堆区开辟的情况,这时候父类指针的管理不到了,在堆区的内存造成泄漏!

例如:

#include<iostream>
using namespace std;

class calculator
{
public:
    virtual int getresult() = 0;
    calculator()
    {
        cout << "父类构造" << endl;
    }
    ~calculator()
    {
        cout << "父类析构" << endl;
    }
public:
    int n1;
    int n2;
};

class add : public calculator 
{
public:
    add()
    {
        cout << "子类构造" << endl;
    }
    ~add()
    {
        cout << "子类析构" << endl;
    }
    int getresult()
    {
        return n1 + n2;
    }
};

int main()
{
    calculator *cal = new add;
    cal->n1 = 10;
    cal->n2 = 20;
    cout << cal->getresult() << endl;
    delete cal;
}

最后的结果没有调用子类析构。

在这里插入图片描述
所以需要对析构函数进行特殊操作:将父类中的析构函数改为虚析构或纯虚析构

#include<iostream>
using namespace std;

class Base
{
public:
    Base()
    {
        cout << "父类构造" << endl;
    }
    virtual ~Base() = 0;//写成纯虚析构的形式,也可以虚析构
};
Base::~Base()
{
    cout << "父类析构" << endl;
}

class son : public Base 
{
public:
    son(int a)
    {
        this->m_a = new int(a);
        cout << "子类构造" << endl;
    }
    ~son()
    {
        cout << "子类析构" << endl;
        if(this->m_a!=nullptr)
        {
            delete m_a;
            m_a =nullptr;
        }
    }
public:
    int *m_a;
};

int main()
{
    Base *s = new son(1);
    delete s;
    return 0;
}

在这里插入图片描述

笔记:
1.在多态中虚函数往往在父类中是没有任何意义的,主要任务是由子类来重写功能,所以可以改成纯虚函数的形式:
virtual 函数签名 =0;
一旦存在纯虚函数,这个类就被叫做抽象类,抽象类是无法实例化对象的。
2.如果父类是抽象类,子类继承父类而没有重写虚函数,也是抽象类,依旧不可以实例化对象。
3.当父类指针指向在堆区开辟的子类对象时,如果父类无虚析构,delete父类指针,子类析构都不会被调用;当父类有虚析构,delete父类指针,先析构子类,再析构父类。
4.也就是说,一旦子类中有指针属性,父类必须写虚析构或纯虚析构

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值