拷貝建構函式是一種特殊的建構函式,函式的名稱必須和類名稱一致,它的唯一的乙個引數是本型別的乙個引用變數,該引數是const型別,不可變的。例如:類x的拷貝建構函式的形式為x(x& x)。
以下情況都會呼叫拷貝建構函式:
乙個物件以值傳遞的方式傳入函式體
乙個物件以值傳遞的方式從函式返回
乙個物件需要通過另外乙個物件進行初始化。
如果在類中沒有顯式地宣告乙個拷貝建構函式,那麼,編譯器將會自動生成乙個預設的拷貝建構函式,該建構函式完成物件之間的位拷貝。位拷貝又稱淺拷貝,後面將進行說明。
自定義拷貝建構函式是一種良好的程式設計風格,它可以阻止編譯器形成預設的拷貝建構函式,提高原始碼效率。
淺拷貝和深拷貝
在某些狀況下,類內成員變數需要動態開闢堆記憶體,如果實行位拷貝,也就是把物件裡的值完全複製給另乙個物件,如a=b。這時,如果b中有乙個成員變數指標已經申請了記憶體,那a中的那個成員變數也指向同一塊記憶體。這就出現了問題:當b把記憶體釋放了(如:析構),這時a內的指標就是野指標了,出現執行錯誤。
深拷貝和淺拷貝可以簡單理解為:如果乙個類擁有資源,當這個類的物件發生複製過程的時候,資源重新分配,這個過程就是深拷貝,反之,沒有重新分配資源,就是淺拷貝。
深拷貝和淺拷貝的定義可以簡單理解成:如果乙個類擁有資源(堆,或者是其它系統資源),當這個類的物件發生複製過程的時候,這個過程就可以叫做深拷貝,反之物件存在資源,但複製過程並未複製資源的情況視為淺拷貝。
淺拷貝資源後在釋放資源的時候會產生資源歸屬不清的情況導致程式執行出錯。
**實現:
拷貝構造:
#include
class test6_1
// 拷貝構造
test6_1(const test6_1 &obj)
~test6_1()
void print()
private:
int m_a;
};// void test(test6_1 &t)
void test(test6_1 t)
test6_1 test6_1()
// 函式返回值是乙個物件
int main6_2()
int main6_1()
預設建構函式:
#include
class
test7_1
test7_1(int a)
void print ()
private:
int m_a;
};// 如果類中沒有定義任何建構函式,編譯器會自動生成乙個無參建構函式,沒有做任何事情
// 如果寫了建構函式,編譯器將不再提供預設的無參建構函式
// 如果還想進行無參構造,需要顯示定義無參建構函式
// 如果沒有定義拷貝建構函式,編譯器會自動生成乙個拷貝建構函式,
// 會做普通型別資料的複製
// 還會生成乙個預設的 析構函式
class
test7_2
test7_2(const test7_2 &obj) {}
~test7_2(){};
#endif
};int main7_1()
深拷貝和淺拷貝:
#include
#include
#include
class test8_1
~test8_1()
printf ("析構被呼叫**********\n");
}void print()
private:
int m_id;
// char m_name[20];
char *m_name;
};// 深拷貝
class test8_2
// 自己寫拷貝建構函式,避免淺拷貝
test8_2(const test8_2 &obj)
~test8_2()
printf ("析構被呼叫**********\n");
}void print()
private:
int m_id;
char *m_name;
};class test8_3
private:
int m_a;
};int main8_3()
int main8_2()
int main8_1()
C 之拷貝建構函式
拷貝建構函式最常見的是當我們建立的物件是用該類的另乙個物件來進行初始化的,此時呼叫的建構函式就是拷貝建構函式。拷貝建構函式實質上就是建構函式的過載。當你不顯式定義拷貝建構函式的時候,c 會給你提供乙個預設拷貝建構函式,這和它提供預設建構函式是一樣的。但是當你一旦顯式定義了建構函式和拷貝建構函式,那麼...
C 拷貝建構函式之深拷貝 淺拷貝
對於普通型別的物件來說,它們之間的複製是很簡單的,例如 int a 88 int b a 而類物件與普通物件不同,類物件內部結構一般較為複雜,存在各種成員變數。下面看乙個類物件拷貝的簡單例子。執行程式,螢幕輸出100。從以上 的執行結果可以看出,系統為物件b分配了記憶體並完成了與物件a的複製過程。就...
c 拷貝函式
2019.6.14 c 拷貝建構函式詳解 一 什麼是拷貝建構函式 首先對於普通型別的物件來說,他們之間的複製是很簡單的,例如 int a 100 int b a 而類物件與普通物件不同,類物件內部結構一般較為複雜,存在各種成員變數。下面看乙個類物件拷貝的簡單例子。includeusing names...