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

C++调用纯虚函数未抛异常 如何触发pure virtual function call错误

问题原因

你写的测试代码没有触发错误,本质是对C构造阶段虚函数调用规则的理解有偏差:
C
构造类对象时,会按照继承链从最顶层基类到最底层派生类逐层执行构造,每进入一层类的构造阶段,对象的虚表指针就会指向当前层对应的虚函数表:

  • 先执行基类A的构造时,虚表中f()是纯虚函数入口,没有可执行的实现
  • 等A构造完成,进入派生类A1的构造阶段时,虚表已经更新为A1的版本,f()已经指向你写的A1::f()实现,这时候你在A1构造函数里调用f(),不管是静态决议还是动态分派,都会调用到已经实现的A1::f(),自然能正常输出,不会报错。

所谓“构造函数里调用虚函数会触发pure virtual function call”是有前提的:调用发生时,当前构造阶段对应的类层级中,被调用的虚函数还是纯虚、没有任何实现。

触发pure virtual function call的常见写法

只要满足上面说的前提,就能触发这个运行时错误,注意不同编译器/运行时的表现有区别:MSVC、Windows下MinGW的C运行时会明确弹出"pure virtual function call"的错误提示,Linux下g可能直接在编译期拦截这类明显错误,或者运行时触发段错误。

写法1:直接在定义纯虚函数的基类构造函数中调用该纯虚函数

#include <cstdio>
class A{
    virtual void f() = 0;
public:
    A() {
        f(); // 执行A的构造时,f()还是纯虚,无实现
    }
};

class A1 : public A{
public:
    void f() override {printf("virtual function");}
};
int main(){
    A1 a;
    return 0;
}

写法2:通过间接调用绕过编译期检查,在基类构造阶段调用纯虚函数

直接在构造函数里写纯虚调用很容易被编译器在编译阶段拦截,通过成员函数、回调、指针间接调用的场景更隐蔽,也是实际开发中最容易踩坑的情况:

#include <cstdio>
class A{
    virtual void f() = 0;
public:
    void invoke() {
        f(); // 封装一层间接调用
    }
    A() {
        invoke(); // 基类构造时通过其他成员函数调用纯虚f
    }
};

class A1 : public A{
public:
    void f() override {printf("virtual function");}
};
int main(){
    A1 a;
    return 0;
}

类似的,构造函数里把this指针传给外部函数、注册为回调,外部代码在构造完成前通过这个指针调用纯虚函数,也会触发同样错误。

另外补充:析构阶段也会出现同类错误——析构顺序是从派生类到基类逐层执行,当执行到基类析构函数时,虚表已经回退到基类版本,这时候调用基类定义的纯虚函数,一样会触发pure virtual function call。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 09:48:22