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...