2012-04-09 195 views
20

我已經使用賦值運算符重載下面的代碼C++超載:賦值運算符在

SimpleCircle SimpleCircle::operator=(const SimpleCircle & rhs) 
{ 
    if(this == &rhs) 
     return *this; 
    itsRadius = rhs.getRadius(); 
    return *this; 
} 

我的拷貝構造函數是這樣的:

SimpleCircle::SimpleCircle(const SimpleCircle & rhs) 
{ 
    itsRadius = rhs.getRadius(); 
} 

在上面的操作符重載的代碼,拷貝構造函數被調用因爲有一個新的對象正在創建;所以我用下面的代碼:

SimpleCircle & SimpleCircle::operator=(const SimpleCircle & rhs) 
{ 
    if(this == &rhs) 
     return *this; 
    itsRadius = rhs.getRadius(); 
    return *this; 
} 

其完美的工作,避免拷貝構造函數問題,但有這方面的任何未知的問題(我)?

+0

看看的[複製和交換成語(http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap -idiom) – Praetorian 2012-04-09 16:37:52

+1

@Praetorian複製和交換成語是好的,如果你知道一個項目可以賦值操作符期間拋出或者如果您正在使用軟件時,您有沒有發展,不知道是否會發生拋出。如果您正在使用自己的物品,並且您知道不會使用副本進行拋出,並且交換習語不是必需的。 – 2015-03-23 23:10:38

回答

10

沒有與賦值運算符的第二個版本沒有問題。實際上,這是賦值運算符的標準方式。

編輯:請注意,我指的是賦值運算符的返回類型,而不是實現本身。正如評論中指出的那樣,執行本身是另一個問題。見here

+3

事實上的標準方式是*複製和交換*方法沒有提到的。 – 2012-04-09 16:33:43

+1

@Als:複製和交換肯定是標準的,當你需要處理遠程所有權。當處理一個簡單的值時,我會稱之爲矯枉過正(儘管仍然可能比問題中的要好)。 – 2012-04-09 16:35:43

+0

@JerryCoffin:其實,我不主張複製和交換的單值調用,因爲它是很難搞砸了複製和交換,一旦你學會了做正確的方式。 – 2012-04-09 16:37:25

4

二是相當標準。您通常更願意返回賦值運算符的引用,以便按預期的方式解析像a = b = c;這樣的語句。我想不出任何我想從作業中返回副本的情況。

有一點需要注意的是,如果你不需要深拷貝它有時被認爲是最好使用編譯器比滾你自己所產生的隱含拷貝構造函數和賦值操作符。真的取決於你雖然...

編輯:

這裏的一些基本通話費:

SimpleCircle x; // default constructor 
SimpleCircle y(x); // copy constructor 
x = y; // assignment operator 

現在說我們有你的賦值運算符的第一個版本:

SimpleCircle SimpleCircle::operator=(const SimpleCircle & rhs) 
{ 
    if(this == &rhs) 
     return *this; // calls copy constructor SimpleCircle(*this) 
    itsRadius = rhs.getRadius(); // copy member 
    return *this; // calls copy constructor 
} 

它調用複製構造函數並將參考傳遞給this以構造要返回的副本。現在,在第二個例子中,我們避免了拷貝由剛剛返回一個參考this

SimpleCircle & SimpleCircle::operator=(const SimpleCircle & rhs) 
{ 
    if(this == &rhs) 
     return *this; // return reference to this (no copy) 
    itsRadius = rhs.getRadius(); // copy member 
    return *this; // return reference to this (no copy) 
} 
+0

其實我想確定這個拷貝構造函數被調用的地方。我正在使用cout <<「我被稱爲」;在那裏面。只有使用它纔會導致問題。它不是複製值。 – kaushik 2012-04-09 16:41:03

+0

我指的是在第一個示例中按值返回副本。 – AJG85 2012-04-09 16:46:32

5

在這種情況下,你幾乎可以肯定是最好跳躍的自我分配的檢查 - 當你只分配一個成員,這似乎是一個簡單的類型(可能是一個雙),它通常更快的做任務不是避開它,所以你最終獲得:

SimpleCircle & SimpleCircle::operator=(const SimpleCircle & rhs) 
{ 
    itsRadius = rhs.getRadius(); // or just `itsRadius = rhs.itsRadius;` 
    return *this; 
} 

我認識許多老人和/或低質量書籍建議檢查自我分配。然而,至少在我的經驗中,如果沒有它,你會變得更好(並且如果操作員依賴它來保證正確性,這幾乎肯定不是例外)。

順便說一句,我會注意的是定義一個圓,你一般需要一箇中心和半徑,當你複製或分配,要複製/分配兩者。

0

這是正確的方式來使用運營商超載 現在你通過引用 避免價值複製你的對象。

-1

,這可能會有所幫助:

// Operator overloading in C++ 
//assignment operator overloading 
#include<iostream> 
using namespace std; 

class Employee 
{ 
private: 
int idNum; 
double salary; 
public: 
Employee () { 
    idNum = 0, salary = 0.0; 
} 

void setValues (int a, int b); 
void operator= (Employee &emp); 

}; 

void Employee::setValues (int idN , int sal) 
{ 

salary = sal; idNum = idN; 

} 

void Employee::operator = (Employee &emp) // Assignment operator overloading function 
{ 
salary = emp.salary; 
} 

int main () 
{ 

Employee emp1; 
emp1.setValues(10,33); 
Employee emp2; 
emp2 = emp1; // emp2 is calling object using assignment operator 

} 
+3

如果您可以解釋發佈的代碼段中的關鍵區域,則可以提供更多的幫助,而不僅僅是發佈代碼片段。 – RinoTom 2013-09-24 14:46:32