当引用返回的对象被销毁时?

时间:2015-11-14 10:59:49

标签: c++ reference return

考虑这两个类(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

2 个答案:

答案 0 :(得分:1)

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

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

重读时,我认为你混淆了两个不同的对象。 def do_something(arg): x=arg x[0] = 9 print "address of x:", id(x) return x y = [1,2] do_something(y) print "address of y:", id(y) 内部创建的<img>iterator可以看到之前被销毁。 iter()中定义的main是另一个对象。它作为第一个的副本开始(但在第一个被销毁后复制)并且作为iter

的局部变量超出正常规则的范围

答案 1 :(得分:0)

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

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

返回的括号在这种情况下没有任何意义。