三規則是衆所周知的,並且說如果必須定義一個析構函數,那麼最有可能定義一個拷貝構造函數和一個賦值運算符。然而,最近在一些代碼中,我偶然發現了一個「二規則」:只定義了析構函數和複製構造函數,並且賦值運算符留給了編譯器來定義。我的第一個想法是「這肯定是一個錯誤」,但現在我不太確定,因爲所有編譯器(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
導致預期的雙免費錯誤。
您從不會在示例代碼中的任何位置調用賦值運算符。 –
@πάνταῥεῖ關於A b = a; ? – ead
請參閱[複製初始化](http://en.cppreference.com/w/cpp/language/copy_initialization)。和'A b; b = a; //這是賦值'。 – songyuanyao