You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++基类非虚函数调用纯虚函数引发Clang链接错误咨询

解析Clang链接错误的原因与解决方案

哈哈,这个问题我之前也踩过一模一样的坑!你困惑的点刚好戳中了C++里纯虚析构函数的一个极易被忽略的特殊规则——纯虚析构函数必须提供定义,这和普通纯虚函数的规则完全不一样。

先还原你的代码场景(根据描述推测)

我猜你的代码大概是这样的:

class Base {
public:
    // 纯虚函数
    virtual void foo() = 0;
    // 调用纯虚函数的普通成员函数
    void bar() { foo(); }
    // 声明为纯虚的析构函数,但没有定义
    virtual ~Base() = 0;
};

class Child : public Base {
public:
    // 实现纯虚函数foo
    void foo() override {
        // 你的业务逻辑
    }
    ~Child() override = default;
};

int main() {
    Child c;
    c.bar(); // 调用基类的bar函数
    return 0;
}

为什么会出现链接错误?

你可能以为问题出在bar()调用纯虚函数foo()上,但其实这部分是完全合法的——因为当你调用c.bar()时,Child对象已经完全构造完成,虚函数表已经正确指向Child的foo实现,这时候调用foo()不会有任何问题。

真正的问题出在对象销毁阶段:当main函数执行完毕,Child对象c会被销毁。C++的析构函数调用链是从最派生类到基类,所以会先调用Child的析构函数,然后自动调用Base的析构函数。而你把Base的析构函数声明为纯虚函数,却没有给它提供定义,链接器找不到这个函数的实现,于是就抛出了链接错误。

这里要纠正你开头的一个误解:你说“无法定义纯虚析构函数”,这是错误的!C++标准明确要求,纯虚析构函数必须有定义——因为派生类的析构一定会调用它,这是纯虚函数里的特例,普通纯虚函数可以不用定义(除非你要显式调用它),但纯虚析构不行。

解决方案

给Base的纯虚析构函数添加一个空定义即可:

// 在类外定义纯虚析构函数
Base::~Base() {}

这样链接器就能找到析构函数的实现,错误就会消失。

额外补充

如果你的代码里Base的析构函数不是纯虚的,那编译器会自动生成一个隐式定义的析构函数,就不会有这个问题。但一旦你把它声明为纯虚,就必须手动提供定义。

内容的提问来源于stack exchange,提问作者koreus737

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:14:31