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

编译器为何将ParameterExpr类判定为抽象类?

这是C++菱形继承的经典坑!我来给你掰明白问题所在

嘿,你的代码里其实藏着一个典型的菱形继承问题,这就是编译器把ParameterExpr判定为抽象类的核心原因:

先拆解你的继承结构

你这是标准的菱形继承链:

  • 最顶层是抽象类IMetaExpression,包含纯虚函数get_type()
  • Expr继承IMetaExpression,并实现了get_type()
  • IParameterExpression也继承IMetaExpression,新增了纯虚函数get_parameter()
  • 最后ParameterExpr同时继承Expr和IParameterExpression

问题的核心:非虚拟继承导致的重复基类实例

C++默认的继承是非虚拟继承,这意味着ParameterExpr对象内部会包含两个完全独立的IMetaExpression子对象:一个来自Expr分支,一个来自IParameterExpression分支。

虽然Expr实现了get_type(),但它只覆盖了自己分支里那个IMetaExpression的纯虚函数;而IParameterExpression分支里的IMetaExpression的get_type()仍然是未实现的纯虚状态。编译器检测到类里还有未完成的纯虚函数,自然就判定ParameterExpr是抽象类,不允许实例化。

解决方法:用虚拟继承合并重复基类

只需要把Expr和IParameterExpression对IMetaExpression的继承改成虚拟继承,就能让整个继承体系里只存在一个IMetaExpression实例。这样Expr实现的get_type()就能覆盖这个唯一的纯虚函数,ParameterExpr也就不再是抽象类了。

修改后的代码如下:

class IMetaExpression { 
public: 
    virtual int get_type(void) = 0; 
    virtual ~IMetaExpression(){} 
}; 
// 加上virtual关键字,虚拟继承IMetaExpression
class IParameterExpression : public virtual IMetaExpression { 
public: 
    virtual char get_parameter(void) = 0; 
}; 
// 同样加上virtual
class Expr : public virtual IMetaExpression { 
public: 
    virtual int get_type(void) override { return 0; } 
}; 
class ParameterExpr : public Expr, public IParameterExpression { 
public: 
    virtual char get_parameter(void) override { return 'c';} 
}; 
int main() { 
    auto p = new ParameterExpr(); 
    p->get_type(); 
    delete p; 
    return 0; 
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 19:54:05