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

为何将C++类数据成员改为引用后程序输出异常?

问题解析:引用成员变量导致析构时丢失字符串内容的原因

先给大家还原下场景:
原本的test类中,name是普通的string成员,运行代码后输出完全符合预期:

#include <iostream>
#include <string>
using namespace std;
class test {
    string name; // non-reference
public:
    test(string name1 = "default") :name (name1) { cout << name << " is constructed"<< endl;}
    ~test() { cout << name << " is destructed"<<endl;}
};
int main() {
    test t1("Mike");
    test t2;
}

输出:

Mike is constructed
default is constructed
default is destructed
Mike is destructed

但把name改成引用类型string &name后,析构时的输出就丢了名字:
修改后的类代码:

class test {
    string &name; // **Make it reference**
public:
    test(string name1 = "default") :name (name1) { cout << name << " is constructed"<< endl;}
    ~test() { cout << name << " is destructed"<<endl;}
};

输出:

Mike is constructed
default is constructed
is destructed
is destructed

核心原因:引用绑定了生命周期极短的局部临时对象

咱们一步步拆解问题:

  • 当你调用test t1("Mike")时,字符串字面量"Mike"会先隐式构造一个临时的string对象,然后构造函数的形参name1(string类型)会拷贝这个临时对象,成为构造函数栈帧里的局部变量。
  • 你的引用成员name直接绑定到了这个局部的name1上。但构造函数执行完毕后,它的栈帧会被销毁,局部变量name1也会被析构——这时候name就变成了悬空引用,指向的对象已经不存在了。
  • 等到析构函数执行时,你尝试访问这个悬空引用的name,这属于C++里的未定义行为,这里刚好表现为输出空字符串,所以只打印出is destructed。

test t2;的情况完全一样:默认参数"default"会构造一个临时string作为形参name1,引用绑定后,构造函数结束name1被析构,析构时引用悬空,自然读不到内容。

对比原代码的正常逻辑

原代码中name是普通的string成员,构造函数里是把name1的值拷贝给name,name成为类对象自己的独立成员,生命周期和类对象完全一致,所以析构时能正常访问并打印名字。

题外话:如果想用引用成员该怎么做?

如果一定要用引用类型的成员,你得确保引用绑定的对象生命周期比类对象更长:

  • 比如把构造函数参数改成const string& name1,并且传入一个全局变量、或者main里的局部变量(生命周期覆盖类对象);
  • 绝对不能绑定到构造函数的局部形参或者临时对象上,否则必然出现悬空引用的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:42:17