2011-04-14 32 views
4

我從「Effective C++」中讀到了這個,這是Col.10。 它說這是讓賦值操作符返回* this的引用的好方法。 我寫了一段代碼片段來測試這個想法。我在這裏重寫了賦值操作符並對其進行了測試。一切安好。 但是,當我刪除該操作符重寫時,一切都是一樣的。這意味着,鏈接分配仍然運作良好。那麼,我錯過了什麼?這是爲什麼?需要你們的解釋,謝謝。賦值操作符在C++中返回* this的引用

#include <iostream> 

using namespace std; 

class Widget{ 
public: 

    Widget& operator=(int rhs) 
    { 
     return *this; 
    } 
    int value; 

}; 

int main() 
{ 
    Widget mywidget; 
    mywidget.value = 1; 
    Widget mywidget2; 
    mywidget2.value = 2; 
    Widget mywidget3 ; 
    mywidget3.value = 3; 
    mywidget = mywidget2 = mywidget3; 
    cout << mywidget.value<<endl; 
    cout << mywidget2.value<<endl; 
    cout << mywidget3.value<<endl; 

} 

回答

6

如果完全刪除operator=方法,缺省operator=將由編譯器,它實現淺拷貝並返回*this參考創建。

順便說一句,當你寫

mywidget = mywidget2 = mywidget3; 

你實際上調用這個默認operator=,因爲你的重載操作符的設計在右側int s到工作。

鏈接的賦值將停止工作,而如果返回值,例如const引用(=>您將收到編譯錯誤)或引用與*this不同的東西(違反直覺的東西將開始發生)。

部分相關:copy and swap idiom,即編寫賦值運算符的完美方式。強烈建議,如果你需要編寫讀取operator=


  1. 默認好像有左手操作數的每個成員,右手一個的每個成員之間的分配operator=將執行。這意味着對於原始類型而言,它將是一個「殘酷」的按位副本,在90%的情況下,對指向自有資源的指針並不確定。
+0

哦,我明白了。那麼,我是否應該始終在我的代碼中執行此操作?或者只是讓編譯器來處理它? – 2011-04-14 21:20:14

+3

如果你的類需要它,你需要實現'operator =',即如果默認的按位複製不正確。這通常發生在當你擁有由你的類擁有的資源的內存/句柄的原始指針時;一個好的經驗法則是,如果你需要一個析構函數來釋放一些資源,你可能需要一個'operator ='來避免不同實例之間不必要的資源共享,雙重釋放和資源泄漏。 – 2011-04-14 21:22:25

+2

不是一個真正的按位複製......對於那些沒有自己的'運營商='會執行按位副本的成員,但實現它(想上'的std :: string')成員現有'運算符= '會員將被使用。 – 2011-04-14 21:26:37

1

Widget& operator=(int rhs)

這允許您指定一個INT到窗口小部件 - 例如mywidget = 3;

製作一個Widget& operator=(Widget const & rhs) - 它將被要求您的mywidget = mywidget2 = mywidget3;線。

你不需要需要operator=(Widget const & rhs)雖然 - 默認應該沒問題。

此外,它可能是一個好主意,例如, cout << "operator=(int rhs)\n";給你的自定義操作符 - 那麼你會發現它在你的代碼中根本沒有被調用。

4

這個問題涉及兩個不同的概念,不管你是否應該定義operator=以及是否應該返回對象的引用。

你應該考慮的三個規則:如果你定義拷貝構造函數賦值運算符析構函數你應該定義他們三人中的一個。圍繞這一規則的理由是,如果你需要提供一個析構函數就意味着你的管理資源,並在這樣做,很可能默認拷貝構造函數賦值運算符不會削減它。舉個例子,如果你通過一個原始指針保存內存,那麼你需要在析構函數中釋放內存。如果你不提供拷貝構造函數賦值運算符,然後將鼠標指針會被複制和兩個不同的對象會嘗試以釋放指針舉行的記憶。

雖然指針是最常見的示例,但這適用於任何資源。 禁用複製構造和分配的類別除外 - 但是,您再次以某種方式將其定義爲它們是已禁用

關於問題的第二部分,或者是否應該返回一個對象的引用,你應該。與所有其他運算符重載一樣,其原因通常是模擬現有的基本類型運算符所提供的建議。這有時是由一個報價給出:運算符重載時,請執行int就做