C 深拷貝與淺拷貝 詳解與案例分析

2021-10-09 20:43:49 字數 1935 閱讀 5395

int a=1;

int*p;

p=new

int(a)

;

前面已說,在定義乙個類時,若不自己提供拷貝建構函式,系統提供乙個預設的拷貝建構函式,這個拷貝拷貝建構函式的傳遞方式為值傳遞。那麼當程式設計師有在堆區開闢記憶體空間時,若依舊不提供拷貝建構函式,則通過拷貝建構函式建立出的新的物件,它的屬性值會與前乙個物件的屬性值是相同的。具體點,由於有堆區開闢空間,那麼上述所說屬性值基本屬於指標型別。這便意味著,有兩個指標,指向同乙個堆區的記憶體位址。當程式執行結束時,系統會自動呼叫析構函式對堆區記憶體進行釋放,這必然導致同乙個堆區記憶體位址被釋放兩次,這是絕不允許的,程式直接終止報錯。以下為錯誤**:

using

namespace std;

#include

#include

class

book

book

(int page1, string name)

//有參建構函式

~book()

};void

test()

intmain()

執行之後的崩潰介面:

從上圖也可以看出,程式要結束時,第乙個析構函式執行成功,但第二個析構未能成功執行。這也側面反映出記憶體重複釋放了導致出錯。

這便是淺拷貝。即建構函式的實現是簡單的賦值傳遞(值傳遞)

那如何解決淺拷貝帶來的問題呢?深拷貝實現。

如有在堆區開闢記憶體,則應該自己提供拷貝建構函式,通過在堆區開闢新的空間來儲存相同的屬性值。這麼做的結果便是兩個指標分別指向兩個不同的堆區位址,由此解決記憶體重複釋放的問題。此為深拷貝。

以下為深拷貝示例**:

using

namespace std;

#include

#include

class

book

book

(int page1, string name)

//引用傳遞

book

(const book& b1)

~book()

cout <<

"book的析構函式呼叫"

<< endl;}}

;void

test()

intmain()

上述**採用引用傳遞方式,其執行結果為:

可以看到,最後兩個析構函式均執行成功,程式未報錯。

也可改為指標傳遞方式,**附上:

using

namespace std;

#include

#include

class

book

book

(int page1, string name)

//指標傳遞

book

(const book *b1)

~book()

cout <<

"book的析構函式呼叫"

執行成功。

奮鬥的人們,加油幹吧!

C 深拷貝與淺拷貝 詳解

include using namespace std class test test test int p,int n test test void test show int main void test a b,88 a.show 上面的拷貝建構函式不夠正規,現在寫乙個常用的拷貝建構函式 in...

C 深拷貝 與 淺拷貝

最近在寫一些c 程式,遇到個問題,記憶體會出錯,查了一些材料,終於發現問題所在了,原來碰到了傳說中的深拷貝和淺拷貝問題了,檢視一些材料,現在對這個問題做個總結 在類定義中,預設是淺拷貝,即 位拷貝 用在基本類中或者一些沒有指標的自定義型別中沒有一點問題,但是當遇到含有指標變數的自定義型別的時候,就會...

C 淺拷貝與深拷貝

淺拷貝 shallow copy 指的是當物件的字段被拷貝的時候,字段應用的物件不會被拷貝。深拷貝是對物件例項當中的字段引用的物件也進行拷貝的一種方式。淺拷貝可以通過將類實現介面icloneable class myclass icloneable 舉個簡單的例項 using system usin...