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
相关产品推荐
相关产品推荐

