2009-10-18 45 views
1

所以我期待通过一些代码,我看到:分配一个C++出参考销毁的东西?

class whatever 
{ 
public: 
    void SomeFunc(SomeClass& outVal) 
    { 
     outVal = m_q.front(); 
     m_q.pop(); 
    } 

private: 
    std::queue<SomeClass> m_q; 
}; 

这似乎并不像outVal将是一个有效的参考更多...但是,它似乎工作。

我以前也在其他代码中看到过,这是否有效?谢谢

+1

我认为这是考虑如果* *会重新安装的参考会发生什么有用的。如果你这样做会发生什么:'int&r = * new int;删除&r;',之后'r'什么也没有引用。我认为这是好的,只要你在删除之后不再评估'r'。所以这是UB:'int&r = * new int;删除&r; R等'。 – 2009-10-19 00:34:50

回答

6

请记住,引用不像指针:它们在创建后不能被反弹。这意味着如果我这样做

int a; 
int b; 
int &c = a; 

然后在整个范围内,对c的分配实际上意味着分配给a。所以,

int a = 2; 
{ 
    int b = 3; 
    int &c = a; 
    c = b; 
    b = -5; 
} 
printf("%d",a); // prints "3". 

因此,在这种情况下,参考是不指着已删除的对象。相反,m_q.front()的返回值是通过赋值运算符复制到任何outVal引用。

+0

确切地说,那里有一个副本。即使看起来outval超出范围,请记住它不是本地函数,只是外部变量的别名。 – AntonioMO 2009-10-18 23:58:23

+0

是的,即使经过几年的C++引用仍然困扰着我有时:)。指针看起来更直观! – Polaris878 2009-10-19 00:04:50

+0

是的,我从来没有真正看到使用C++引用而不是指针的任何价值。 – Crashworks 2009-10-19 06:44:41

2

我在前面的回复中写的是完全废话。 (谁回复了我的原始回复,请收回:)

在此示例中,引用未绑定到正在死亡的对象,而是前端对象的值被复制到另一个对象(由参考)。副本继续独立于队列存在,队列前端被销毁的事实对副本没有不利影响。

请参阅Crashworks回复,以获取有关此处发生的事情的最佳解释。

+0

没有让你满意,但是-1因为你要求和+1来承认和纠正自己的错误。让我们说,我们甚至:) – 2009-10-19 01:57:17

2

这是有效的。您不重置outVal引用来引用m_q.front(),这不是引用支持的东西,而是将m_q.front()分配给outVal引用的变量(实际上是左值)。

SomeClass c; 
    someWhatever.SomeFunc(c); 

可以被认为是表现得像:

SomeClass c; 
    c = someWhatever.m_q.front(); 
    someWhater.m_q.pop();