2012-03-21 33 views
6

我做了以下測試:爲什麼在分配前有一份副本?

#include <iostream> 
#include <vector> 

using namespace std; 
class A 
{ 
private: 
    int i; 
public: 
    A():i(1){cout<<"A constr"<<endl;} 
    A(const A & a):i(a.i){cout<<"A copy"<<endl;} 
    virtual ~A(){cout<<"destruct A"<<endl;} 
    void operator=(const A a){cout<<"A assign"<<endl;} 
}; 


int main() 
{ 
    A o1; 
    A o2; 
    o2=o1; 
} 

,輸出是:

A constr 
A constr 
A copy 
A assign 
destruct A 
destruct A 
destruct A 

看來,「02 = 01」做一個備份,然後分配,我不知道有什麼故事背後。謝謝!

回答

15

因爲你按值傳遞到你的賦值運算符:

void operator=(const A a) 

你可能意味着按引用傳遞,你也應該返回一個參考分配到對象:

A& operator=(const A& a) { std::cout << "A assign" << std::endl; return *this; } 
4

你似乎設置了你的賦值操作符才能正確實現:

T& T::operator= (T value) { 
    value. swap(*this); 
    return *this; 
} 

a參數通過複製傳遞給assigment操作符,編譯器實際需要在您的設置中執行此副本。如果你已通過一個臨時本來是可以避免的副本:

o2 = A(); 

因此,上述實際執行有一些有趣的特性:

  • 它利用已寫入功能:拷貝構造函數或者是產生或書面,但沒有正確的事情,如果你想有一個任務,你可能想要有swap()成員以及
  • 如果swap()操作是非拋出,它應該是強大的異常安全。當分配器輸入圖片的事情需要做略有不同,雖然
  • 分配儘量避免實際的複製操作作爲參數傳遞過程中副本可以在某些情況下被省略,即內容僅僅是swap()編入到位
相關問題