如果基类是抽象类(含纯虚函数),但忘记给纯虚析构函数提供实现,会发生什么?

先看一个问题,为什么基类的析构函数应该声明为virtual?

class Base {
public:
    ~Base() { cout << "Base destructor" << endl; }  // 非虚析构函数
};

class Derived : public Base {
public:
    ~Derived() { cout << "Derived destructor" << endl; }
};

int main() {
    Base* obj = new Derived();
    delete obj;  // 猜猜会输出什么?
}

▶ 你的预测结果是?实际运行后会发现:

  • 仅输出 Base destructor
  • Derived 的析构函数没有被调用!

这就是问题的本质

  1. 当通过基类指针删除派生类对象时,如果析构函数不是虚函数:

    • 编译器根据指针类型(Base*)决定调用哪个析构函数
    • 派生类的析构函数被跳过 → ​资源泄漏
  2. 正确的做法:

class Base {
public:
    virtual ~Base() { cout << "Base destructor" << endl; }  // 虚析构函数
};

此时输出:

Derived destructor
Base destructor

深层原理​:

  • 虚函数表(vtable)机制保证正确调用实际对象的析构函数
  • 析构函数的调用顺序:派生类 → 基类(与构造顺序相反)

底层原理​(编译器行为):

// 伪代码展示delete obj时的实际操作
if (obj != nullptr) {
    // 1. 通过虚函数表找到实际对象的析构函数
    void (*dtor)(void*) = obj->vptr[-1];  
    // 2. 先调用派生类析构函数
    dtor(obj);  
    // 3. 再调用operator delete释放内存
    operator delete(obj);  
}

重要推论​:

  • 如果一个类可能被继承(即使现在没有),且会通过基类指针操作对象:
    ⇒ 必须声明虚析构函数
  • 但不需要所有类都加virtual(会带来额外开销)

再来看这个问题:如果基类是抽象类(含纯虚函数),但忘记给纯虚析构函数提供实现,会发生什么?

这个问题非常具有陷阱性!先看这个看似正常的代码:

class AbstractBase {
public:
    virtual ~AbstractBase() = 0;  // 纯虚析构函数声明
    virtual void foo() = 0;       // 其他纯虚函数
};

class Concrete : public AbstractBase {
public:
    ~Concrete() override { cout << "Concrete destroyed" << endl; }
    void foo() override {}
};

int main() {
    AbstractBase* obj = new Concrete();
    obj->foo();
    delete obj;  // 这里会发生什么?
}

▶ ​运行时会直接崩溃,错误通常是:

undefined reference to `AbstractBase::~AbstractBase()'

根本原因​:

  1. 纯虚析构函数仍然需要实现​(与其他纯虚函数不同!)
  2. 析构函数调用链的机制决定了:
    • 即使派生类实现了自己的析构函数
    • 编译器仍会尝试调用基类的析构函数

内存中的真实调用顺序​(伪代码):

// 当执行 delete obj 时:
1. 调用 Concrete::~Concrete()
2. 调用 AbstractBase::~AbstractBase()  // 如果这里没有实现→链接错误
3. 调用 operator delete()

正确写法​:

class AbstractBase {
public:
    virtual ~AbstractBase() = 0;  // 纯虚声明
};
// 必须提供实现(通常在.cpp文件中)
AbstractBase::~AbstractBase() { /* 可空实现 */ } 

关键区别​:

特性普通纯虚函数纯虚析构函数
是否需要实现派生类必须实现基类和派生类都要实现
可否内联实现不可以可以
典型用途强制接口实现强制抽象基类+清理资源

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值