C 淺拷貝和深拷貝的區別

2021-09-29 18:40:51 字數 2253 閱讀 4095

深淺拷貝是面試面試經典問題

c++中的建構函式有三類,預設建構函式,有參建構函式,拷貝建構函式。

首先考慮一種情況,對乙個已經定義的物件進行拷貝,編譯器會呼叫建構函式中的拷貝建構函式。

淺拷貝: 如果使用者沒有定義自己的拷貝建構函式,則會呼叫預設的拷貝建構函式。預設拷貝建構函式中會對物件中的變數進行簡單的賦值拷貝操作,就是乙個等號賦值操作,這種操作就是淺拷貝。

深拷貝: 而深拷貝就是在堆區重新申請一塊空間,來進行拷貝賦值操作。

在下面的程式中,我們先定義乙個dog1物件,並將dog1拷貝給dog2

#include

using

namespace std;

class

dogdog

(int age)

~dog()

};intmain()

由於這個時候我們沒有自定義拷貝建構函式,所以編譯器呼叫了預設的拷貝建構函式,也就是完成了淺拷貝,將dog1的年齡拷貝給了dog2。函式執行結果:

dog的有參建構函式  

dog1的年齡為:5

dog2的年齡為:5

dog的析構函式

dog的析構函式

此時我們增加dog大小的變數d_size,我們將變數定義在堆區,堆區的變數需要我們手動釋放,所以在析構函式中我們需要將堆區開闢的資料釋放。執行下方程式

#include

using

namespace std;

class

dogdog

(int age,

int sizze)

~dog()

cout <<

"dog的析構函式"

<< endl;}}

;int

main()

這時候程式崩了。。。

為什麼會這樣子呢?我們剛才建立了兩個物件,dog1和dog1的複製品dog2,如果利用編譯器提供的拷貝建構函式,會做淺拷貝操作。也就是把dog1的的d_age和dog1的d_size複製給dog2,這裡d_size是我們在堆區用new建立的乙個變數,所以儲存的是乙個位址。淺拷貝會直接將dog1中的d_age(儲存的是5)和d_size(儲存的是變數的位址)中的值複製給dog2,所以dog2中的d_age和d_size儲存的也就是5和變數的位址。當呼叫析構函式的時候,dog1和dog2都會執行析構函式,由於dog1和dog2是儲存在棧中,先進後出,所以dog2先呼叫析構函式,先將d_size中的位址對應的堆區中的記憶體釋放,然後dog1再執行析構函式中釋放記憶體操作,由於同一塊位址的記憶體已經被釋放過了,所以程式就崩了。如下圖

淺拷貝帶來的問題就是堆區的記憶體重複釋放。淺拷貝的問題,需要利用深拷貝進行解決。由於編譯器提供的淺拷貝不能滿足要求,我們要自己實現乙個拷貝建構函式,來解決淺拷貝帶來的問題。

#include

using

namespace std;

class

dogdog

(int age,

int dsize)

dog(

const dog &p)

~dog()

cout <<

"dog的析構函式"

<< endl;}}

;int

main()

這次程式沒有崩掉,完美執行~ 由於我們在拷貝建構函式中重新開闢了堆區的記憶體,則變數結構如下

dog的有參建構函式

dog1的年齡為:5大小為:40

dog的拷貝建構函式

dog2的年齡為:5大小為:40

dog的析構函式

dog的析構函式

總結:淺拷貝就是編譯器實現的直接等號複製操作,深拷貝重新申請一塊空間,進行拷貝操作,所以如果物件中有屬性在堆區中開闢的,一定要自己提供拷貝建構函式,防止淺拷貝帶來的問題。

C 淺拷貝和深拷貝的區別

c 預設的拷貝建構函式是淺拷貝 淺拷貝就是物件的資料成員之間的簡單賦值,如你設計了乙個沒有類而沒有提供它的複製建構函式,當用該類的乙個物件去給令乙個物件賦值時所執行的過程就是淺拷貝,如 class a a private int data int main 這一句b a 就是淺拷貝,執行完這句後b....

C 淺拷貝和深拷貝的區別

對於普通型別的物件來說,它們之間的複製是很簡單的,例如 int a 88 int b a 而類物件與普通物件不同,類物件內部結構一般較為複雜,存在各種成員變數。下面看乙個類物件拷貝的簡單例子。iostream using namespace std class cexample void show ...

c 深拷貝和淺拷貝的區別

其實深拷貝和淺拷貝都涉及到c 中的物件拷貝的問題,所謂物件拷貝就是為物件建立副本,得到相同的物件 而深拷貝和淺拷貝的區別就在於,深拷貝完全將物件中的所有欄位都複製到副本物件中,但是不管拷貝的物件是引用型別字段還是值型別字段,都會被重新建立並複製,副本物件內的值並不會因為源物件資料的值得修改而改變 相...