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

C++中type& var=*ptr与type var=*ptr的行为差异解析

两种Foo对象使用场景的差异解释

首先给出类定义:

class Foo {
public:
    Foo(int a) {
        aa = a;
        cout << "foo built. " << aa << endl;
    }
    ~Foo() {
        cout << "foo DIED. " << aa << endl;
    }

    int aa;
};

以及函数定义:

Foo* func1(){
    Foo* foo = new Foo(1);
    return foo;
}

情况1:执行后输出"foo DIED"的代码块

{ // <---- 代码块范围
    Foo obj = *func1();
}

情况2:执行后不会释放Foo实例的代码块

{
    Foo &obj = *func1();
}

差异原因解析

  • 情况1:值拷贝生成栈上对象
    func1()用new在堆上创建了一个Foo对象,返回它的指针。*func1()是对指针解引用,拿到堆上的原对象。Foo obj = *func1();这一步会触发拷贝构造,在栈上生成一个和原对象一模一样的新Foo实例obj。
    当代码块结束时,栈上的局部对象obj会被自动销毁,调用它的析构函数,所以会输出"foo DIED. 1"。但要注意:堆上的原对象根本没被释放,这里已经造成了内存泄漏,只是栈上的副本被销毁了而已。

  • 情况2:引用只是原对象的别名
    Foo &obj = *func1();是把栈上的引用obj直接绑定到堆上的原Foo对象。引用不是新对象,只是原对象的一个"外号",不会额外创建实例。
    代码块结束时,引用的生命周期走到头,但它指向的堆上对象不会自动销毁——因为用new创建的对象必须手动调用delete才能释放内存。所以堆上的Foo实例还留在内存里,不会触发析构函数,自然不会输出"foo DIED",同样也造成了内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 11:42:52