继承之虚析构函数

2021-01-15  本文已影响0人  井底蛙蛙呱呱呱

虚析构函数使得我们在使用抽象类声明/定义一个子类时,可以调用该子类的析构函数。

借用职工管理系统中的一个例子:普通工人,经理,老板可以继承自一个抽象工人类。

#include <iostream>
#include <string>

using namespace std;



// 职工抽象类
class Workers {
public:
    // 显示职工信息
    virtual void show_info()=0;

    // 获取岗位名称
    virtual string getDeptName()=0;

    virtual ~Workers() = default;

    int m_Id; // 职工编号
    string m_Name; // 职工姓名
    int m_DeptId; // 职工部门
};

//Workers::~Workers(){
//
//}

class Boss: public Workers{
public:
    // 构造函数
    Boss(int id, string name, int dept_id){
        this->m_Id = id;
        this->m_Name = name;
        this->m_DeptId = dept_id;
    };

    // 显示员工信息
    void show_info(){
        cout << "职工编号:" << this->m_Id
             << "\t职工姓名:" << this->m_Name
             << "\t职工岗位:" << this->getDeptName()
             << "\t岗位职责:管理全部事务"
             << endl;
    };

    // 获取岗位信息
    string getDeptName(){
        return string("老板");
    };

    //~Boss(){};
};


class Manager: public Workers {
public:
    // 构造函数
    Manager(int id, string name, int dept_id){
        cout << "职工编号:" << this->m_Id
             << "\t职工姓名:" << this->m_Name
             << "\t职工岗位:" << this->getDeptName()
             << "\t岗位职责:完成老板交给的任务,并下发任务给普通员工"
             << endl;
    };

    // 显示函数
    void show_info(){
        cout << "职工编号:" << this->m_Id
             << "\t职工姓名:" << this->m_Name
             << "\t职工岗位:" << this->getDeptName()
             << "\t岗位职责:完成老板交给的任务,并下发任务给普通员工"
             << endl;
    };

    // 获取岗位信息
    string getDeptName(){
        return string("经理");
    };

    //~Manager(){};
};

class Employee: public Workers {
public:
    // 构造函数
    Employee(int id, string name, int dept_id){
        this->m_Id = id;
        this->m_Name = name;
        this->m_DeptId = dept_id;
    };

    // 显示个人信息
    void show_info(){
        cout << "职工编号:" << this->m_Id
             << "\t职工姓名:" << this->m_Name
             << "\t职工岗位:" << this->getDeptName()
             << "\t岗位职责:完成经理交给的任务"
             << endl;
    };

    // 获取岗位信息
    string getDeptName(){
        return string("员工");
    };

    // 析构函数
    //~Employee(){};
};

int main(){

    Workers * worker = NULL;
    // 测试普通员工类
    worker = new Employee(1, "张三", 3);
    worker->show_info();
    // cout << &worker << endl;
    // cout << *(&worker) << endl;
    // string wname = worker->getDeptName();

    // cout << wname << endl;
    delete worker;

    // 测试经理类
    // Workers * worker2;
    worker = new Manager(2, "李四", 2);
    worker->show_info();
    delete worker;
    // cout << &worker << endl;
    // cout << *(&worker) << endl;

    // 测试boss类
    // Workers * worker3;
    worker = new Boss(3, "王五", 1);
    worker->show_info();
    delete worker;
    // cout << &worker << endl;
    // cout << *(&worker) << endl;
    cout << "hello world" << endl;
    cout << &worker << endl;
}

在上面的例子中,Workers类为基类且为抽象类。如果我们不把Workers类中的析构函数定义为虚函数,当我们通过抽象类来声明实例化一个子类对象时,虽然基类的属性方法都通过指针指向了子类的实现。但是当我们delete boss实例时,却无法将boss实例给删掉,因为没有将基类的析构函数定义为虚函数。

当我们将基类的析构函数的定义为虚函数,删除子类对象时便能通过基类指针指向子类的析构函数从而成功析构掉子类对象。这在子类对象有用到堆区内存时非常重要,可以避免内存泄漏。

参考:
C++中虚析构函数的作用
虚函数和纯虚函数的区别

上一篇下一篇

猜你喜欢

热点阅读