拷貝構造函數
假設我們有一個類Body,其形式如下:
class Body{
Body(int a):m_a(a) {}; // 構造函數
~Body() {}; // 析構函數
int m_a;
};
在這個類中有一個隱含的拷貝構造函數如下:
class Body{
Body(int a):m_a(a) {}; // 構造函數
~Body() {}; // 析構函數
Body(const Body& body) { // 拷貝構造函數(人工寫出來的形式)
m_a = a;
}
int m_a;
};
這個隱含的拷貝構造函數是一個淺拷貝,也就是對成員變量簡單的進行賦值。在大多數情況下,這種淺拷貝能滿足我們的要求。但是當類中出現動態變量時,這種淺拷貝不能滿足要求,因爲其2個類的指針變量公用一個堆。需要我們自己顯式的寫拷貝構造函數(深拷貝)。
class Body{
Body(int a):m_a(a) {
m_pb = new int;
}; // 構造函數
~Body() {}; // 析構函數
Body(const Body& body) { // 拷貝構造函數
m_a = a;
m_pb = new int;
*m_pb = *(body.m_pb);
}
int m_a;
int* m_pb;
};
拷貝構造函數什麼時候被調用
1 當用類的一個對象初始化該類的另一個對象時.例如:
int main()
{
point A(1,2);
point B(A);//用對象A初始化對象B,拷貝構造函數被調用.
}
2 如果函數的形參是類的對象,調用函數時,進行形參和實參結合時.
void f(point p)
{
}
main()
{
point A(1,2);
f(A); //函數的形參爲類的對象時,當調用函數時,拷貝構造函數被調用.
}
3 如果函數的返回值是類的對象,函數執行完成返回調用者時.
point g()
{
point A(1,2);
return A; //函數的返回值是類的對象,返回函數值時,調用拷貝構造函數.
}
void main()
{
point B;
B = g();
}
4、需要產生一個臨時類對象時。