【问题标题】:When a object returned by reference is destroyed?当引用返回的对象被销毁时?
【发布时间】:2016-02-15 21:58:55
【问题描述】:

考虑这两个类(List<Type>List<Type>::iterator

// List<Type>
template<typename Type>
class List {
public:
    class iterator;
    iterator& iter();

private:
    Type *elems; // Array
};

// List<type>::iterator
template<typename Type>
class List<Type>::iterator {
public:
    Type *current;
    Type operator* ();

private:
    iterator (Type *current) : current(current) {}
};

template<typename Type>
typename List<Type>::iterator& List<Type>::iter () {
    return (iterator(this->elems));
}

// Program
int main () {
    List<int> *list = new List<int>();
    List<int>::iterator iter = list->iter(); // When does iter get destroyed?
    delete list;
}

我读到了这个带括号 return (...); 的返回,可以说是引用返回。我不确定,但我认为iter 是在堆栈上创建的(因为没有new)。所以我的问题是:iter 何时超出范围?在iter() 之后,main() 之后或其他地方?我必须手动delete 吗?

【问题讨论】:

  • 你为什么在这里使用指针List&lt;int&gt; *list?你是用new分配的吗?
  • +πάντα-ῥεῖ 是的,我将List&lt;int&gt;new 一起分配,并且我还在原始代码中的某处将其删除。我实际上缩短了这里的代码。

标签: c++ reference return


【解决方案1】:

您返回了对临时对象的引用,因此它在调用者甚至可以访问该引用之前就被销毁(您有未定义的行为)。

您从哪里(在哪里)读到“带括号返回”的内容?据我了解,当编译器必须推断返回类型时,这会产生重要影响。但是您指定了返回类型,所以这些括号应该没有区别。如果你读到与此不同的东西,你在哪里读到了什么?

重读时,我认为您混淆了两个不同的对象。在iter() 内部创建的iteratormain 看到之前就被销毁了。 main 中定义的 iter 是一个不同的对象。它作为第一个的副本开始(但在第一个被销毁后复制)并超出正常规则的范围作为main的局部变量

【讨论】:

  • 现在你解开了我的困惑 :) 为了引用这个括号,我浏览了这篇关于“返回语句中括号的重要性”的帖子 (stackoverflow.com/questions/4762662)。
【解决方案2】:

此代码不应编译。您正在返回对临时对象的可变引用,这在 C++ 标准下是非法的。

即使它是一个 const ref,您也会返回一个对本地的引用,这是未定义的行为。

在这种情况下,return 周围的括号没有任何意义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-02
    • 1970-01-01
    • 1970-01-01
    • 2011-02-23
    • 2014-03-18
    • 2012-04-24
    • 2013-10-24
    • 1970-01-01
    相关资源
    最近更新 更多