C++基类的虚析构函数问题abstract but has non-virtual destructor

发布时间 2023-06-18 23:22:30作者: 3的4次方

C++基类的虚析构函数问题abstract but has non-virtual destructor

C++条款:如果类存在虚函数,如果类要作为基类的话,一定要在析构函数定义为virtual

派生类可以分配内存或保留对销毁对象时需要清除的其他资源的引用。如果不为接口/抽象类提供虚拟析构函数,则每次通过基类指针删除派生类实例时(即多态),都不会调用派生类的析构函数(因为指针是基类类型的指针)。也就意味着内存泄漏。而虚析构函数将允许基类指针将派生类的对象安全的删除,因此抽象基类必须写上virtual的析构函数。

C++类的constructor不能是virtual的,因为语言就这么规定的,创建对象时必需知道对象的准确类型和内存布局。

而类的destructor不一定要是virtual的,这与是否有继承没关系,只有当你需要用base class pointer析构sub class object的时候才需要在base class中定义virtual destructor,否则destructor无法体现多态性,导致只能析构掉一个base class slice,其它属于sub class的部分可能会泄露。

例子:

class Worker{
public:
    // 显示个人信息
    virtual void showInfo() = 0;
    // 获取部门名称
    virtual string getDeptName() = 0;
    int m_Id;  //职工编号
    string m_Name;  // 职工姓名
    int m_DeptId;  // 职工部门编号
};
class Employee : public Worker{
public:
    // 构造函数
    Employee(int id,string name,int deptId);
    // 显示个人信息
    virtual void showInfo();
    // 获取部门信息
    virtual string getDeptName();
};

Worker * worker = NULL;
worker = new Employee(1,"name",1);
delete worker; //这里不行,报错:Delete called on 'Worker' that is abstract but has non-virtual destructor

解决方案:

virtual ~Worker(){} // 在基类加上虚析构函数