2009-10-18 19 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();