【问题标题】:What gets returned return type is reference of object?返回的返回类型是对象的引用?
【发布时间】:2012-08-20 21:41:49
【问题描述】:

这就是我所相信的:

当函数返回时,它会创建对象的新临时副本,并且此临时对象在调用它的语句期间保留在内存中。

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

所以当我这样做时:

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

在 main() 中我做

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

它在两者中都打印垃圾。

返回什么? : 对 g 的本地副本的引用,即函数完成后立即销毁的 cl 或对语句结束后被销毁的临时对象的引用。但是因为如果 temp 被创建,它将以正确的方式覆盖 d。所以我相信返回的是传递值的 localcopy 的引用。

但是,一旦我在结构中创建了析构函数,它就完美地运行了,并带有以下代码和特定的输出。

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

输出:

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

此输出显示每次调用只创建一个对象。 (有两个调用)

但是为什么没有析构函数就不能工作呢?

谢谢

【问题讨论】:

  • 此类情况的结果是否未定义?

标签: c++ oop object reference destructor


【解决方案1】:
 MyStruct & ReferenceReturn(MyStruct cl)
 {
         return cl;
 }

创建temporary object,将其分配给cl,将reference返回给对象,销毁对象。所以,它是dangling reference。编译器可以使用copy-elision 并且不复制对象,但不能...使用一些lile

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

【讨论】:

  • 我发现该对象在声明后被破坏。当我添加析构函数时,它的输出是在 cout
  • @ASHISHNEGI 在 copy-ctor 中插入跟踪怎么样? liveworkspace.org/code/8077039f76b8b4a52d09977b94f31155 但在 MSVC 中结果不一样。因此,按照标准,这种用法是不正确的。
  • 如您所见,传递的对象的析构函数输出“d-tor”在打印“0”的语句“cout”之后调用,这意味着该对象在该语句完成之前是好的。所以它的工作..但是当我删除析构函数和复制构造函数时;在我的情况下会打印垃圾。
  • @ASHISHNEGI 按照标准这是不正确的。这种情况在编译器中的实现是未定义的。
【解决方案2】:
 MyStruct & ReferenceReturn(MyStruct cl) {
    return cl;
 }

这种情况的结果是否未定义?

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

【讨论】:

  • “可能在调用者使用引用之前”没有析构函数你是对的;当我正确解构器时,会发生其他事情-> 函数的本地副本在 cout 语句之后被破坏。所以析构函数在这里做一些事情,否则就像你说的那样是未定义的。
  • @ASHISHNEGI:我不知道如何才能更清楚:该函数表现出未定义的行为。未定义的行为意味着它似乎可以工作,或者它可能会提供不正确的结果或使应用程序崩溃,但在所有情况下它仍然是未定义的行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-11
  • 2013-10-30
  • 1970-01-01
  • 1970-01-01
  • 2017-01-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多