C 之深拷貝 淺拷貝

2021-09-26 20:18:41 字數 1616 閱讀 1092

什麼是拷貝建構函式?

通過拷貝物件的方式建立乙個新的物件,拷貝建構函式的引數必須是類物件的引用,也就是將乙個物件拷貝給另乙個新建的物件(用途,在建立物件的時候,使用同一類之前建立的物件來初始化新建立的物件)

book(book &b);//必須是引用的原因是,如果是傳值方式將實參傳遞給形參,中間要經歷乙個物件的拷貝,物件拷貝由必須呼叫拷貝建構函式,這樣就形成乙個死迴圈,無解
拷貝建構函式第乙個引數一定是物件的引用,後面如果有其他引數,要給出預設值,否則就預設不寫

book(book &b,price = 5.0);
如果沒有顯示的宣告乙個拷貝建構函式,系統會自動為類生成乙個拷貝建構函式,自動生成的僅僅將物件的所有成員變數複製給當前建立的物件(淺拷貝)

為了乙個類中包含動態分配儲存空間的指標型別的成員變數時,就必須為這個類設計乙個拷貝建構函式,還要為他新增乙個賦值操作符過載函式,過載(=)

為了不讓物件發生拷貝行為,我們可以顯示宣告乙個拷貝建構函式,並將其設定為private屬性

什麼是淺拷貝?

資料成員之間的簡單複製,系統預設的拷貝建構函式實現的就是淺拷貝

預設的拷貝建構函式實現對資料成員一一賦值,但是如果類中含有指標型別的資料,這種拷貝只是將指標簡單的拷貝,並沒有分配新的記憶體

運算子「=」的過載就是實現淺拷貝的原因,由於物件之間含有指標資料型別,a , b恰好指向同一塊記憶體,就是淺拷貝

當兩個物件的指標指向同一塊記憶體時,呼叫第乙個的析構函式會釋放一次記憶體,呼叫第二個又會把這個釋放過的記憶體再次釋放一次

對同乙個動態記憶體釋放兩次以上結果時未定義的,容易導致記憶體洩露和程式崩潰。此時就需要深拷貝解決問題

注意:淺拷貝帶來問題的本質在於析構函式釋放多次堆記憶體,使用std::shared_ptr,可以完美解決這個問題。

什麼是深拷貝?

為賦值物件申請了乙個新的記憶體

當拷貝物件中有其他資源(堆)的引用時,物件另開闢一塊新的資源,而不再對拷貝物件有其他資源的引用的指標或引用進行單純的賦值

為了解決淺拷貝的問題,必須顯示的定義拷貝建構函式,不但可以複製資料成員,還可以為物件分配各自的記憶體空間

深拷貝不僅對指標進行拷貝,對指標指向的內容也拷貝,也就是給物件新分配了一塊記憶體,經過深拷貝後的指標是指向不同位址

對於普通成員的賦值,深拷貝淺拷貝都是一樣的。

參見c++ primer第5版p448頁

/* 深拷貝淺拷貝 */

#include

using

namespace std;

class

a//建構函式初始化a(

)public

:int data;};

class

b//建構函式初始化b(

);b(

const b &x)

:num

(x.num)

//深拷貝,增加了這一句拷貝建構函式,程式就不會崩潰~b

()public

:int

*data;

int num;};

intmain()

C 之深拷貝 淺拷貝

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

C 深拷貝 淺拷貝

c 深拷貝 淺拷貝 深拷貝 淺拷貝和直接指向引用的區別 深拷貝 淺拷貝都是重新開闢了記憶體空間,並且在新的記憶體空間裡面賦了物件本身 的值。直接指向引用是乙個物件直接指向另外乙個物件的引用,這兩個物件指向的是同一 塊記憶體空間,操作任乙個物件都會影響另外的物件。深拷貝和淺拷貝的區別 如果物件的成員都...

C 淺拷貝 深拷貝

簡單的來說就是,在有指標的情況下,淺拷貝只是增加了乙個指標指向已經存在的記憶體,而深拷貝就是增加乙個指標並且申請乙個新的記憶體,使這個增加的指標指向這個新的記憶體,採用深拷貝的情況下,釋放記憶體的時候就不會出現 在淺拷貝時重複釋放同一記憶體 的錯誤!你正在編寫c 程式中有時用到,操作符的過載。最能體...