拷貝建構函式,預設拷貝建構函式
1.c++的預設拷貝建構函式,從深度拷貝和淺拷貝說起
c++類的預設拷貝建構函式的弊端
c++類的中有兩個特殊的建構函式,(1)無參建構函式,(2)拷貝建構函式。它們的特殊之處在於:
(1)當類中沒有定義任何建構函式時,編譯器會預設提供乙個無參建構函式且其函式體為空;
(2)當類中沒有定義拷貝建構函式時,編譯器會預設提供乙個拷貝建構函式,進行成員變數之間的拷貝。(這個拷貝操作是淺拷貝)
class testcls;
int main(void)
編譯執行確實不會出錯:
類在我們沒有定義拷貝建構函式的時候,會預設定義預設拷貝建構函式,也就是說可以直接用同型別的類間可以相互賦值、初始化:
int main(void)
這樣結果就會出錯。
原因就在於,預設的拷貝建構函式實現的是淺拷貝。
2.深度拷貝和淺拷貝
深度拷貝和淺拷貝在c語言中就經常遇到的了,在這裡我簡單描述。
一般的賦值操作是深度拷貝:
//深度拷貝
int a = 5;
int b = a;
簡單的指標指向,則是淺拷貝:
//淺拷貝
int a = 8;
int *p;
p = &a;
char* str1 = 「helloworld」;
char* str2 = str1;
將上面的淺拷貝改為深度拷貝後:
//深度拷貝
int a = 8;
int *p = new int;
*p = a;
char* str1 = 「helloworld」;
int len = strlen(str1);
char *str2 = new char[len];
memcpy(str2, str1, len);
能看得出深度拷貝和淺拷貝的差異。拷貝者和被拷貝者若是同乙個位址,則為淺拷貝,反之為深拷貝。
以字串拷貝為例,淺拷貝後,str1和str2同指向0x123456,不管哪乙個指標,對該空間內容的修改都會影響另乙個指標。
深拷貝後,str1和str2指向不同的記憶體空間,各自的空間的內容一樣。因為空間不同,所以不管哪乙個指標,對該空間內容的修改都不會影響另乙個指標。
解決預設拷貝建構函式的弊端
類的預設拷貝建構函式只會用被拷貝類的成員的值為拷貝類簡單初始化,也就是說二者的p指標指向的記憶體空間是一致的。以前面testcls可以知道,編譯器為我們預設定義的拷貝建構函式為:
testcls(const testcls& testcls)
main函式將要退出時,拷貝類t2的析構函式先得到執行,它把自身p指向的堆空間釋放了;接下來,t1的析構函式得到呼叫,被拷貝類t1的析構函式得到呼叫,它同樣要去析構自身的p指向指向的堆空間,但是該空間和t2類中p指向的空間一樣,造成重複釋放,程式執行崩潰。
解決辦法就是自定義拷貝建構函式;
class testcls
預設拷貝建構函式
1.什麼時候用到拷貝建構函式?以乙個已經存在的物件初始化同型別的另乙個物件時,如 class a a a a aa a 作為函式引數時,產生臨時物件,呼叫拷貝建構函式進行初始化 void fun a a 作為函式返回值時,產生臨時物件 a fun a a return a 產生臨時物件,並呼叫拷貝建...
自定義拷貝建構函式 預設的拷貝建構函式
自定義拷貝建構函式 類名 類名 const 類名 物件名 拷貝建構函式的函式體 利用下述語句呼叫拷貝建構函式 rectangle p2 p1 include using namespace std class rectangle public rectangle int len,int wid le...
C 有關拷貝建構函式(預設 淺 深拷貝建構函式)
拷貝結構函式顧名思義就是複製物件。先講一下預設拷貝函式 預設拷貝就是直接賦值,讓程式呼叫預設拷貝結構函式。student p1 student p2 p1 或者student p2 p1 程式開始執行時,建立p1物件,p1物件的建構函式從堆中分配空間並賦給資料成員pname,執行,p2 p1時,因為...