2010-07-06 74 views
4

親愛的朋友們,我很擔心,如果我做不好的使用C++ 在下面的方法GCC引用訴說警告「引用局部變量‘我’回來」返回引用++方法

MatrizEsparsa& MatrizEsparsa::operator+(MatrizEsparsa& outra){ 
    MatrizEsparsa me(outra.linhas(),outra.colunas()); 
    return me; 
} 

但是,有以下變化的警告消失:

MatrizEsparsa& MatrizEsparsa::operator+(MatrizEsparsa& outra){ 
    MatrizEsparsa me(outra.linhas(),outra.colunas()); 
    MatrizEsparsa &ref = me; 
    return ref; 
} 

是前一種方法(返回「裁判」變量)正確\接受嗎?

+0

對我來說都不好看 – 2010-07-06 13:30:20

+1

@Chris Card:可能是'MatrizEsparsa&'。 @Lucas:'operator +'通常應該是一個獨立的函數來允許隱式類型轉換。請參閱有效的C++,第24項。 – Philipp 2010-07-06 13:32:50

+1

對問題+1,因爲學習如何隱藏編譯器的錯誤總是很有趣:D – ereOn 2010-07-06 13:39:45

回答

13

ref仍指me,在通話結束時將被銷燬。

您應該返回結果的副本(前綴爲&)。

MatrizEsparsa MatrizEsparsa::operator+(const MatrizEsparsa& outra) const { 
    return MatrizEsparsa(outra.linhas(),outra.colunas()); 
} 

我還添加了兩個const說明符(將參數和所述方法),因爲我懷疑outra或調用實例需要在這種情況下進行修改。 (我可能是錯的,但那麼你的operator+會有一個奇怪的語義)

通過做你做的,你只是使代碼更復雜。編譯器可能很困惑,無法警告你可能的錯誤。

通常,當你不得不使用巧妙的技巧來做簡單的事情時,這意味着有些事情是錯誤的。

2

不,您必須在此處返回一個值,理想情況下爲const值。見收效C++,第21項

,我建議如下界面:

const MatrizEsparsa operator+(const MatrizEsparsa& left, const MatrizEsparsa& right); 

注意,一切要麼是const引用或const值。返回const值並不像返回一個值或聲明參數爲const引用那麼重要,但Scott Meyers的論點讓我確信,儘管沒有人遵循它們。

+0

結果的不變性是另一場辯論。返回一個const引用會順便說一句,仍然是不正確的。 – ereOn 2010-07-06 13:32:40

+0

我會購買並閱讀Effective C++,謝謝! – Lucas 2010-07-06 13:44:09

+0

@ereOn:是的,Effective C++中的建議解決方案是一個常量值。 const引用是(或者至少在C++ 0x之前)通常用作函數的返回類型,例如不需要創建新對象的'std :: min'。 – Philipp 2010-07-06 13:58:43

2

這是不可接受的。它實際上是同樣的問題:返回一個非const引用到一個本地對象,該對象將在返回該方法後被銷燬。

+5

爲什麼強調非const?返回一個const引用將會有問題... – fredoverflow 2010-07-06 13:44:25

+0

我想知道:在標準中沒有什麼東西要求如果必要的話,綁定到const引用的對象的生命週期被擴展,以便const引用是有效的? 'Foo const&result = foo1 + foo2'是有效的,即使典型的'+'運算符返回一個副本,但我不知道它是否適用於返回... – 2010-07-06 17:23:31

4

我認爲你錯在操作員。

有2個:

struct Foo 
{ 
    Foo& operator+=(Foo const&); 
    Foo operator+(Foo const&) const; 
}; 

你可能注意到了,首先返回到自身的引用,第二個沒有。

另外,一般來說,第二個應該寫成一個自由函數。

Foo operator+(Foo const&, Foo const&); 

這可以自動化,因爲它的繁瑣,使用Boost.Operators:

struct Foo: boost::addable<Foo> 
{ 
    Foo& operator+=(Foo const& rhs) 
    { 
    // add 
    return *this; 
    } 
}; 

boost::addable魔術會自動生成基於Foo::operator+=+實施。

+0

+1:對於很好的boost ::可添加的技巧。 – ereOn 2010-07-07 05:58:33

0

您不能返回引用,因爲您引用的對象將在您的控件之外被銷燬。或者把「我」作爲MatrizEsparsa的成員變量,以便它在執行該函數後保持不變,否則返回一個指向該對象的指針或提升smart_ptr。

雖然這是一個+運算符,但您可能希望返回一個值而不是對函數內部變量的引用。