深拷貝與淺拷貝

2021-07-31 11:04:05 字數 3410 閱讀 5686

-------------------siwuxie095

深拷貝

與淺拷貝

物件間的拷貝沒那麼簡單,大致分為兩種情況:一種叫做

深拷貝,一種叫做

淺拷貝看如下例項:定義乙個陣列類:array

使用時:

arr1 在例項化時,會呼叫建構函式,而使用 arr1 初始化 arr2,

arr2 在例項化時,就會呼叫拷貝建構函式,引數其實就是 arr1

上面的例子比較簡單,對其再做稍微地修改:加乙個

int 型指標,該指標

在建構函式中從堆中申請了一段記憶體,且指向了堆中的這段記憶體,記憶體的

大小就是

m_icount,而拷貝建構函式的實現方法還是進行簡單的拷貝

使用時:arr1 執行預設建構函式,而 arr1 初始化 arr2 時,就會呼叫拷貝

建構函式,但這兩個例子都只是將資料成員的值進行了簡單的拷貝,這種

拷貝模式稱為

淺拷貝但對於第乙個例子,使用淺拷貝的方式實現拷貝建構函式並沒有任何問題,

而對於第二個例子,肯定是有問題的

經過淺拷貝之後,物件

arr1 中的指標和物件 arr2 中的指標勢必會指向同

一塊記憶體,因為在拷貝建構函式中,將

arr1 的 m_parr 賦值給了 arr2 的

m_parr,使得這兩個變數中存放的是同乙個值

此時,如果先給 arr1 的 m_parr 賦了一些值,再去給 arr2 的 m_parr

賦值時,這段記憶體就會被重寫,覆蓋掉

arr1 的 m_parr 的值,最嚴重

的是,當銷毀 arr1 物件時,為了避免記憶體洩露,肯定會釋放掉

arr1 中

m_parr 所指向的這段記憶體,如果已經釋放掉這段記憶體,再去銷毀

arr2

物件時,也會以同樣的方式釋放掉 arr2 中 m_parr 所指向的這段記憶體

相當於同一塊記憶體被釋放了兩次,這種情況肯定是有問題的,面對這種

問題,計算機會以崩潰的方式向你**,提示的錯誤資訊因為晦澀難懂,

不能直奔主題,同樣使得初學者感到崩潰 …

所以,希望拷貝建構函式所完成的工作應該是這樣的:兩個物件的指標

所指向的應該是不同的記憶體,拷貝時不是將指標的位址簡單地拷貝過來,

而是將指標所指向的記憶體中的每乙個元素依次拷貝過來

**應該寫成這樣:

兩種拷貝方式有著本質的區別,當進行物件拷貝時,不是簡單地做值的

拷貝,而是將堆中記憶體的資料也進行拷貝,這種拷貝模式稱為

深拷貝程式 1:淺拷貝

array.h:

classarray ;

array.cpp:

#include"array.h"

#include

using namespacestd;

array::array()

array::array(intcount)

array::array(constarray &arr)

array::~array()

voidarray::setcount(intcount)

intarray::getcount()

voidarray::printaddr()

voidarray::printarr() }

main.cpp:

#include

#include"array.h"

#include

using namespacestd;

//淺拷貝:將值直接拷貝過去

intmain(void)

執行一覽:

程式 2:深拷貝

array.h:

classarray ;

array.cpp:

#include"array.h"

#include

using namespacestd;

array::array(intcount)

cout << "array"<< endl;

}array::array(constarray &arr)

cout << "array &"<< endl;}//

此為淺拷貝:

//arr2

的指標和

arr1

的指標指向同一塊記憶體,當給

arr1

賦值後再給

arr2賦值,

會覆蓋掉

arr1

的值//

在析構時同一塊記憶體會

delete

兩次導致錯誤

//array::array(const array &arr)

//array::~array()

voidarray::setcount(intcount)

intarray::getcount()

voidarray::printaddr()

voidarray::printarr()

cout << endl;}

main.cpp:

#include

#include"array.h"

#include

using namespacestd;

//深拷貝:先申請一段記憶體,再將傳入進來的物件的對應

//位置的記憶體拷貝到申請的記憶體中去

intmain(void)

執行一覽:

「淺拷貝」與「深拷貝」

c 中物件的複製就如同 轉殖 用乙個已有的物件快速地複製出多個完全相同的物件。一般而言,以下三種情況都會使用到物件的複製 1 建立乙個新物件,並用另乙個同類的已有物件對新物件進行初始化,例如 cpp view plain copy class rect rect rect1 rect rect2 r...

淺拷貝與深拷貝

淺拷貝 1 2 myclass a,b a b 為了封裝性和解耦,同型別的兩個物件之間進行賦值操作時,所有成員變數被複製,包括私有成員 指標變數。類的成員函式在傳遞或返回物件時都會進行物件複製產生臨時物件,比如函式呼叫時實參變為形參,以及函式返回物件。考慮到效能和使用者要求不同,編譯器不複製物件內部...

「淺拷貝」與「深拷貝」

c 中物件的複製就如同 轉殖 用乙個已有的物件快速地複製出多個完全相同的物件。一般而言,以下三種情況都會使用到物件的複製 1 建立乙個新物件,並用另乙個同類的已有物件對新物件進行初始化,例如 cpp view plain copy class rect rect rect1 rect rect2 r...