2012-08-25 128 views
0

这是我相信的:得到返回的返回类型是对象的引用吗?

当一个函数返回它时,创建一个新的临时对象副本,并且这个临时对象保留在内存中,从它被调用的地方开始。

当函数返回该对象本身返回的引用时。这意味着该对象不应该是本地的。

所以,当我这样做:

MyStruct & ReferenceReturn(MyStruct cl) 
{ 
     return cl; 
} 

在main()我做

MyStruct d("notmyname"),g("myname"); 
d = ReferenceReturn(g); 
cout << d.name; 
cout << ReferenceReturn(g).name; 

打印不需要的两个。

返回什么? :引用g的本地拷贝,即一旦函数完成就被销毁,或者在语句结束后对临时对象的引用被销毁。但是,既然温度已经被创造出来,它就会以正确的方式超越。所以我相信它是返回的传递值的localcopy的参考。

但是,只要我在结构中进行析构函数,它就完美了,具有以下代码和特定的输出。

~MyStruct() 
{ 
    cout << name << " is destroying"; 
    } 

输出:

myname is destroying 
myname 
myname 
myname is destroying 
.... 

此输出显示只有一个对象是为每一个呼叫建立。 (有两个电话)

但是,为什么它不工作没有析构函数?

感谢

+0

结果未定义为这种情况? –

回答

2
MyStruct & ReferenceReturn(MyStruct cl) 
{ 
     return cl; 
} 

创建temporary object,将其分配给cl,返回reference为对象,销毁对象。所以,它是dangling reference。编译器可以使用copy-elision不要复制的对象,但不能...使用的东西LILE

MyStruct & ReferenceReturn(MyStruct& cl) 
{ 
     return cl; 
} 
+0

我发现该对象在声明后遭到破坏。当我添加析构函数时,它的输出是在cout << ReferenceResult(g)<< endl;这样在完成这一行后,对象就会被破坏。 –

+0

@ASHISHNEGI如何在copy-ctor中插入轨迹? http://liveworkspace.org/code/8077039f76b8b4a52d09977b94f31155但在MSVC结果不一样。所以,这种用法在标准上是不正确的。 – ForEveR

+0

正如你所看到的,在语句“cout”打印“0”之后调用传入对象的析构函数ouput“d-tor”,这意味着该对象在该语句完成之前是好的。所以它的工作..但是当我删除析构函数和复制构造函数;垃圾被打印在我的情况。 –

1
MyStruct & ReferenceReturn(MyStruct cl) { 
    return cl; 
} 

是结果未定义这种情况?

该函数表现出未定义的行为,是的。问题是cl是函数中的本地对象,并且您正在返回对其的引用。这是未定义的行为。调用者将创建g的副本以传递到ReferenceReturn,并且该副本将在return之后被ReferenceReturn函数销毁,可能在调用方使用该引用之前。

+0

“可能在调用者使用引用之前”没有析构函数,你是对的;当我正确destuctor别的事情发生 - >本地复制的功能正在越来越被破坏后的cout声明。所以在这里做析构函数或者它是不确定的,就像你说的那样。 –

+0

@ASHISHNEGI:我不知道如何让它更清晰:函数表现出未定义的行为。未定义的行为意味着它看起来可以工作,或者它可能提供不正确的结果或使应用程序崩溃,但在所有情况下它仍然是未定义的行为。 –