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

为什么两次调用getter方法之间C++类对象的成员值会发生变化?

问题根因分析

你遇到的异常返回是典型的悬空引用导致的未定义行为,具体原因如下:

#include<iostream>

using namespace std;

class Test {
public:
    int &t; // 引用类型成员
    Test (int x):t(x) { } // 构造函数值传递形参x
    int getT() { return t; }
};

int main() {
    int x = 20;
    Test t1(x);
    cout << t1.getT() << " ";
    cout << t1.getT() << endl;
    return 0;
}
  • 构造函数的形参x是值传递的局部临时变量,仅在构造函数执行期间存活,构造函数执行结束后,x占用的栈内存会被释放,标记为可复用。
  • 初始化列表中将引用成员t直接绑定到了临时形参x上,构造结束后t就变成了没有合法绑定对象的悬空引用,访问悬空引用属于C++标准规定的未定义行为。
  • 第一次调用getT()时,刚完成构造,x占用的栈内存还没有被其他操作覆盖,因此大概率能读到初始值20;第一次cout调用会占用栈空间写入数据,覆盖了原来x的内存位置,第二次调用getT()读取到的就是被覆盖后的垃圾值,因此返回结果不符合预期。
修复方案

可以选择任意一种适配你的业务需求的修改方式:

  1. 若需要保留成员的引用语义,将构造函数形参改为引用类型,让引用成员绑定到外部的长期存活对象上:
// 构造函数修改为引用传参
Test (int &x):t(x) { }

修改后t绑定的是main函数中定义的变量x,只要main函数未执行结束,x就不会被释放,不会出现悬空问题。
2. 若不需要引用语义,直接将类成员改为普通int类型即可:

// 成员变量改为普通int类型
int t;
Test (int x):t(x) { }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 12:15:04