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

C++父类调用派生类虚函数出现纯虚方法调用报错如何解决

根因分析

你的推测有误,该报错和&A::thread_f的写法无关,核心是C++对象构造期间的虚函数绑定规则:

  • 派生类对象构造时,会优先执行基类的构造逻辑,此时派生类自身的成员和虚函数表还未完成初始化,虚表指针暂时指向基类A的虚表
  • 你在A的构造函数中直接启动了线程,线程执行时机不受控制:如果线程在B类完全构造完成前就执行了thread_f中的f()调用,此时调用的是A类的纯虚函数f(),没有实际实现,就会触发「pure virtual method called」报错

修复方案

方案1:拆分构造和线程启动逻辑(最推荐)

不要在基类构造函数中启动线程,新增显式启动接口,等派生类完全构造完成后再手动调用,无额外同步开销,逻辑最清晰:

class A {
protected:
    std::thread _thread;

    A() {} // 构造函数不再启动线程

    ~A() { 
        if (_thread.joinable())
            _thread.join();
    }

    virtual void f() = 0;

    void thread_f() {
        f();
    }

    // 新增启动接口
    void start() {
        _thread = std::thread(&A::thread_f, this);
    }
};

class B : public A {
protected:
    void f() override {
        std::cout << "B::f()" << std::endl;
    }
};

// 使用示例
int main() {
    B b;
    b.start(); // 等B完全构造完成后再启动线程
    return 0;
}

方案2:增加同步等待标识

如果需要保留构造自动启动线程的逻辑,可以在基类增加原子标识控制线程执行时机,派生类构造完成后再放开执行权限:

#include <atomic>
#include <thread>
class A {
protected:
    std::thread _thread;
    std::atomic<bool> _init_done = false;

    A() : _thread(&A::thread_f, this) { }

    ~A() { 
        _thread.join();
    }

    virtual void f() = 0;

    void thread_f() {
        while (!_init_done) {
            std::this_thread::yield();
        }
        f();
    }
};

class B : public A {
public:
    B() {
        _init_done = true; // 自身构造完成后修改标识
    }
protected:
    void f() override {
        std::cout << "B::f()" << std::endl;
    }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 23:45:00