2011-04-09 219 views
13

編譯器是否生成賦值運算符防止自賦值?賦值運算符 - 自賦值

class T { 

    int x; 
public: 
    T(int X = 0): x(X) {} 
}; 

int main() 
{ 
    T a(1); 
    a = a; 
} 

即使類成員不是指針類型,我是否總是需要防止自賦值?

+1

沒有,有什麼不妥。我不認爲有什麼需要「防範」的,真的。編輯:你在說複製構造函數嗎? – 2011-04-09 23:11:45

+2

如果沒有類成員是指針/智能類型,那麼答案是否定的。沒有必要防止它。在這種情況下,行爲與POD(普通舊數據)相同... – 0xC0000022L 2011-04-09 23:13:31

回答

12

編譯器是否生成賦值操作符防止自賦值?

不,不。它只是執行一個成員方式的副本,其中每個成員都由自己的賦值運算符(也可能是程序員聲明或編譯器生成的)複製。

即使類成員不是指針類型,我是否總是需要防止自賦值?

不,如果你的班級的所有屬性(因此他們的屬性都是POD-types),你不會。

當寫你自己的賦值操作符,你不妨檢查一下自賦值,如果你想將來證明你的課,即使它們不包含任何指針,等等。另請考慮the copy-and-swap idiom

+1

無論如何,添加,刪除或更改數據成員都需要重新訪問op =(等等),因此不必要的自分配檢查就像未來的保證一樣。 – 2011-04-09 23:58:06

+0

@Fred Nurk:你是對的。不幸的是,重新訪問'operator ='新的或改變的屬性並不能保證維護者會做正確的事情。 – Johnsyweb 2011-04-10 00:08:05

+2

@Johnsyweb:添加一個不必要的自分配檢查也不能保證維護者會做正確的事情,但更可能會困惑於知道他們在做什麼的人。例如:「不必要」在這裏很重要,因爲複製類型經常是自行分配(罕見)的代價會受益於檢查,即使它不是絕對必要的。 – 2011-04-10 01:30:40

4

這是一個容易憑經驗檢查:

#include <iostream> 
struct A { 
    void operator=(const A& rhs) { 
    if(this==&rhs) std::cout << "Self-assigned\n"; 
    } 
}; 

struct B { 
    A a; 
}; 

int main() 
{ 
    B b; 
    b = b; 
} 
+1

不錯!這無疑證明了* current *編譯器的行爲。 – Johnsyweb 2011-04-10 02:02:13

-1
class T { 
    int x; 
public: 
    T(int X = 0): x(X) {} 
// prevent copying 
private: 
    T& operator=(const T&); 
}; 
+1

它似乎並不是我想要禁用賦值運算符。 (S)他想使用它,但有一個自我分配的問題。 (此外,你的代碼有一個錯字。) – 2012-06-14 08:05:09