深拷貝與淺拷貝的區別

2021-09-24 19:36:45 字數 1202 閱讀 6963

參考:

先考慮一種情況,對乙個已知物件進行拷貝,編譯系統會自動呼叫一種建構函式——拷貝建構函式,如果使用者未定義拷貝建構函式,則會呼叫預設拷貝建構函式。

先看乙個例子,有乙個學生類,資料成員時學生的人數和名字:

#include

using namespace std;

class student

;student::student()

student::~student()

int main()

system("pause");

return 0;

}執行結果:呼叫一次建構函式,呼叫兩次析構函式,兩個物件的指標成員所指記憶體相同,這會導致什麼問題呢?name指標被分配一次記憶體,但是程式結束時該記憶體卻被釋放了兩次,會導致崩潰!

這是由於編譯系統在我們沒有自己定義拷貝建構函式時,會在拷貝物件時呼叫預設拷貝建構函式,進行的是淺拷貝!即對指標name拷貝後會出現兩個指標指向同乙個記憶體空間。

所以,在對含有指標成員的物件進行拷貝時,必須要自己定義拷貝建構函式,使拷貝後的物件指標成員有自己的記憶體空間,即進行深拷貝,這樣就避免了記憶體洩漏發生。

新增了自己定義拷貝建構函式的例子:

#include

using namespace std;

class student

;student::student()

student::~student()

student::student(const student &s)

int main()

system("pause");

return 0;

}執行結果:呼叫一次建構函式,一次自定義拷貝建構函式,兩次析構函式。兩個物件的指標成員所指記憶體不同。

總結:淺拷貝只是對指標的拷貝,拷貝後兩個指標指向同乙個記憶體空間,深拷貝不但對指標進行拷貝,而且對指標指向的內容進行拷貝,經深拷貝後的指標是指向兩個不同位址的指標。

再說幾句:

當物件中存在指標成員時,除了在複製物件時需要考慮自定義拷貝建構函式,還應該考慮以下兩種情形:

1.當函式的引數為物件時,實參傳遞給形參的實際上是實參的乙個拷貝物件,系統自動通過拷貝建構函式實現;

2.當函式的返回值為乙個物件時,該物件實際上是函式內物件的乙個拷貝,用於返回函式呼叫處。

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

淺拷貝與深拷貝的區別

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

淺拷貝與深拷貝的區別

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

淺拷貝與深拷貝的區別

在python中有乙個copy模組。copy.copy 是淺拷貝 copy.deepcopy 是深拷貝 對於不可變型別,無論是淺拷貝還是深拷貝都只是指向作用,沒有進行拷貝,對於可變型別copy.copy 與copy.deepcopy存在差距 import copy a 1,2,3 b 4,5 c a...