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