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

未赋值的ob.derived2::i编译后值为33且总和88,求技术解释

嘿,这个问题其实涉及两个关键知识点:C++里未初始化成员的未定义行为,还有菱形继承带来的重复基类实例。让我给你一步步拆解清楚:

问题核心原因解析

1. 菱形继承导致的双重基类实例

你的代码里是典型的菱形继承结构:

  • base作为基类,derived1和derived2都公开继承自它
  • derived3又同时继承了derived1和derived2

这种情况下,derived3的对象里会包含两个完全独立的base子对象:一个来自derived1分支,另一个来自derived2分支。所以你代码里的ob.derived1::i和ob.derived2::i是两个不同的变量,存在内存的不同位置。

你只给ob.derived1::i赋值了10,但ob.derived2::i自始至终都没被初始化过。

2. 未初始化变量的“垃圾值”本质

在C++中,像main函数里的derived3 ob这种局部对象,它的非静态成员如果没有被显式赋值,其值属于未定义行为——说白了就是这块内存之前用过,残留了一些旧数据(栈内存里的垃圾),程序直接把这些旧数据当成了变量的值。

你看到的33就是这么来的,换个机器运行、或者调整代码里的变量顺序,这个值大概率会变成别的数字,完全是随机的。

3. 关于总和的计算

你代码里的sum = ob.derived2::i + ob.j + ob.k,其中j=20、k=30,加上随机的33的话,结果应该是83?可能你笔误写成了88?不过不管怎样,核心问题还是未初始化的derived2::i取到了栈上的垃圾值。

如何修复这个问题?

如果你希望整个继承体系里只存在一个base实例(让derived1和derived2共享同一个base子对象),可以用虚继承来解决:

// 修改derived1和derived2的继承方式
class derived1 : virtual public base {
public:
    int j;
};
class derived2 : virtual public base {
public:
    int k;
};

这样derived3里就只有一个base子对象,你直接赋值ob.i=10就行,不会再出现两个独立的i,也能避免忘记初始化其中一个的问题。

另外,最好养成初始化所有成员变量的习惯,比如给base添加构造函数,或者在声明成员时直接赋默认值,从根源上避免未定义行为带来的随机值问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:04:23