2017-02-06 30 views
3

三規則是衆所周知的,並且說如果必須定義一個析構函數,那麼最有可能定義一個拷貝構造函數和一個賦值運算符。然而,最近在一些代碼中,我偶然發現了一個「二規則」:只定義了析構函數和複製構造函數,並且賦值運算符留給了編譯器來定義。我的第一個想法是「這肯定是一個錯誤」,但現在我不太確定,因爲所有編譯器(gcc,msvs,intel)都生成了賦值操作符,它調用了拷貝構造函數。編譯器是否定義了賦值運算符來調用複製構造函數?

簡化,該類如下所示:

struct A{ 
    size_t size; 
    int *p; 
    A(size_t s): size(s), p(new int[size]){} 

    A(const A&a): size(a.size), p(new int[size]){ 
     std::copy(a.p, a.p+a.size, p); 
     std::cout<<"copy constructor called\n"; 
    } 

    ~A(){ 
     delete[] p; 
    } 
}; 
像這樣使用

和:

int main(){ 
    A a(2); 
    a.p[0]=42.0; 

    A b=a; 
    std::cout<<"first: "<<b.p[0]<<"\n"; 
} 

產生以下輸出:

copy constructor called 
first: 42 

我的問題:這是guarantied,編譯器定義的賦值操作符將調用拷貝構造函數,或者它只是一個幸運的巧合,編譯器是這樣做的嗎?


編輯:這是真的,我感到困惑初始化和賦值!替換A b=a;A b(0); b=a導致預期的雙免費錯誤。

+2

您從不會在示例代碼中的任何位置調用賦值運算符。 –

+0

@πάνταῥεῖ關於A b = a; ? – ead

+1

請參閱[複製初始化](http://en.cppreference.com/w/cpp/language/copy_initialization)。和'A b; b = a; //這是賦值'。 – songyuanyao

回答

5

這是你誤解發生了什麼,沒有任何分配,只有建設和初始化。

當你

A b = a; 

沒有分配,只有初始化。更確切地說,複製初始化這是相同的寫作

A b(a); 
2

初始化創建一個新的對象:

A a;  // initialization 
A b(a); // initialization 
A c = a; // initialization 

分配修改現有對象:

A a; 
a = 3; // assignment 

在代碼示例中,各種意見都表示,有沒有任務正在完成;所有的例子都是初始化,所以編譯器生成的賦值運算符不被使用。

相關問題