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

规避C++菱形继承问题时存在哪些疏漏?

问题分析与解决

错误根源:虚拟继承的构造规则

你遇到的问题核心是对虚拟继承下虚基类的初始化规则理解有误:

  • 在C++虚拟继承中,只有最派生类(这里是D)有权初始化虚基类(A),中间派生类(B、C)的构造函数里对虚基类A的构造调用会被编译器直接忽略。
  • 你的代码中,D的构造函数没有显式初始化A,所以编译器自动调用A的默认构造函数(A()),把A的x设为5,这就是输出都是5的原因。
  • 另外你预期输出6和7是不符合虚拟继承逻辑的:虚拟继承的目的就是让B和C共享同一个A实例,不可能存在两个独立的A对象分别被B和C初始化。

修正方案

如果需要指定A的x值,必须在最派生类D的构造函数初始化列表中显式调用A的带参构造函数。比如修改D的构造函数:

class D : public B, public C {
    protected:
    int x;
    public:
    // 显式初始化虚基类A,虚基类的构造调用建议放在初始化列表最前面
    D() : A(8), x(35), B(11), C(21) { }
    int get() { return x; }
    void set(int i) { x = i; return *this; }
};

此时d.B::A::get()和d.C::A::get()都会输出8,因为它们访问的是同一个A实例。

补充说明

每个类里的x都是各自独立的成员:A有一个x,B、C、D各自也有自己的x,它们名字相同但属于不同类域,通过::可以区分访问。虚拟继承只影响基类A的实例数量,不影响这些各自的x成员。

内容的提问来源于stack exchange,提问作者Patrick O'Brien

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 14:30:26