C 遠征之淺拷貝與深拷貝

2021-07-27 05:50:03 字數 1434 閱讀 2248

淺拷貝,根據字面意思理解即可,就只是單純的賦值,就像a=5;b=a一樣。通過下面的例子,可能體會更深一些。

class array

array(const array& arr)

private:

int m_icount;

}

首先,我們先定義乙個陣列的

類array,在這個類中定義了乙個建構函式以及乙個拷貝建構函式,並宣告了乙個資料成員m_icount,在建構函式中,為其賦值5,拷貝建構函式中的引數本身就是array型別的,所以arr也必將有乙個m_icount,所以將arr的資料成員的值賦值給拷貝建構函式的m_icount。

int main(void)

例項化arr1時,將呼叫建構函式,對arr1中的m_icount賦值為5。如果我們使用arr1初始化arr2時,就會呼叫到拷貝建構函式,拷貝建構函式中的引數其實就是arr1,然後將

arr1中的m_icount賦值給arr2中的m_icount。

然後我們將這個例子加深一下,變成這樣:

class array

array(const array& arr)

private:

int m_icount;

int *m_parr;

}

我們新增乙個int型別的指標m_parr,在建構函式中,從堆中申請了一塊大小為

m_icount的記憶體,並指向了這塊記憶體。拷貝建構函式中,將arr的

m_parr賦值給當前物件的m_parr。若還是按照原先的方式進行初始化時,就會出現問題,因為arr1中的指標與arr2的指標勢必會指向同一塊記憶體,arr1的指標

m_parr賦值給arr2的指標m_parr,就使得這兩個變數當中存放的是同乙個值,假設這個值就是0x00ff00,那麼就以為這兩個指標指向了同一塊記憶體。

如果我們對arr1中的

m_parr進行賦值操作,然後在對arr2中的m_parr進行賦值操作,那麼這塊記憶體內容將被覆蓋掉重寫,而且這還不是最嚴重的。最嚴重的是,我們為了避免記憶體的洩露,進行完一系列操作後,釋放記憶體,因為arr1與arr2中都有指標m_parr,那勢必會進行兩次記憶體的釋放,而且是同一塊記憶體被釋放了兩次,這顯然是有問題的。為了避免這樣的誤操作,引出了深拷貝。

深拷貝完成的不是簡單的位址拷貝,而是在兩塊不同堆中記憶體上資料進行依次拷貝。

class array

array(const array& arr)

{ m_icount=arr.m_icount;

m_parr=new int[m_icount];

for(int i=0;i

C 之淺拷貝與深拷貝

當我們對類或者結構體進行賦值操作的時候,會呼叫拷貝建構函式,這時會涉及到淺拷貝和深拷貝的問題。一 淺拷貝 所謂淺拷貝就是對資料成員進行簡單的一一拷貝,因此,對於指標變數也只是拷貝了指標本身,當拷貝完成之後,兩個指標會指向同一塊記憶體,所以當呼叫兩次析構函式的時候,該記憶體會被釋放兩次,從而造成指標懸...

C 之深拷貝 淺拷貝

關於拷貝的錯誤 對乙個已知物件進行拷貝,編譯系統會自動呼叫一種建構函式 拷貝建構函式,如果使用者未定義拷貝建構函式,則會呼叫預設拷貝建構函式。以下有乙個學生類 執行結果 呼叫一次建構函式,呼叫兩次析構函式,兩個物件的指標成員所指記憶體相同,這會導致什麼問題呢?name指標被分配一次記憶體,但是程式結...

C 之深拷貝 淺拷貝

什麼是拷貝建構函式?通過拷貝物件的方式建立乙個新的物件,拷貝建構函式的引數必須是類物件的引用,也就是將乙個物件拷貝給另乙個新建的物件 用途,在建立物件的時候,使用同一類之前建立的物件來初始化新建立的物件 book book b 必須是引用的原因是,如果是傳值方式將實參傳遞給形參,中間要經歷乙個物件的...