[英]C++ Why was the copy constructor called?
class A {
public:
A() {}
A(const A& a) { cout << "A::A(A&)" << endl; }
};
class B {
public:
explicit B(A aa) {}
};
int main() {
A a;
B b(a);
return 0;
}
為什么打印“A :: A(A&)”?
什么時候“A”的復制構造函數被稱為? 如果代碼調用了復制構造函數,為什么我可以在不創建編譯錯誤的情況下刪除復制構造函數?
B(A aa)
采用A
by值,因此當您執行B b(a)
,編譯器調用復制構造函數A(const A& a)
以在B
的explicit
構造函數中生成名為aa
的A
實例。
您可以刪除復制構造函數並使其仍然有效的原因是,在您尚未聲明移動構造函數的情況下,編譯器將為您生成復制構造函數。
注意:編譯器生成的復制構造函數通常不足以用於復雜的類,它執行簡單的成員智能復制,因此對於復雜元素或動態分配的內存,您應該聲明自己的。
§15.8.1
如果類定義未顯式聲明復制構造函數,則會隱式聲明非顯式構造函數。 如果類定義聲明了移動構造函數或移動賦值運算符,則隱式聲明的復制構造函數被定義為已刪除; 否則,它被定義為默認(11.4)。 如果類具有用戶聲明的復制賦值運算符或用戶聲明的析構函數或賦值運算符,則不推薦使用后一種情況。
為什么要復制
看看你的class B
c'tor:
class B {
public:
explicit B(A aa) {}
};
您通過值接收A,在通話期間觸發副本。
如果您將其更改為(注意A & aa
):
class B {
public:
explicit B(A & aa) {}
};
沒有任何副本......
默認復制構造函數
當你刪除c'tor時,編譯器會為你生成一個,當它可以這么做時:
首先,你應該明白,如果你沒有聲明一個復制構造函數,編譯器會隱式地給你一個。 隱式復制構造函數執行源對象的成員方復制。
默認c'tor相當於:
MyClass::MyClass( const MyClass& other ) :
x( other.x ), c( other.c ), s( other.s ) {}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.