C 物件導向 6 深拷貝和淺拷貝

2021-10-02 03:37:56 字數 2603 閱讀 4911

前面一直在學習建構函式,其中拷貝構造我們帶出了值傳遞,拷貝乙個物件等概念。這篇來學習一下c++的乙個非常容易面試遇到的問題,也就是學習過程中的乙個坑。什麼是淺拷貝和深拷貝,兩者的區別是什麼。

淺拷貝:簡單的賦值拷貝操作

前面我們學習的拷貝建構函式就是淺拷貝

根據前面的**,我們把point換成person類

#include using namespace std;

class person

person(int age)

public:

int m_age;

};void test01()

int main()

執行結果

本示例**並沒有寫出拷貝構造,但是c++編譯器自動呼叫了拷貝構造,所以p1的年齡也變成了18歲,這個就是淺拷貝的過程。

深拷貝:在堆區重新申請空間,進行拷貝操作

先修改下面**,就是新增乙個身高的屬性,是乙個int型別指標,然後在有參構造裡面是有new關鍵字在堆區開闢乙個空間來新建乙個身高,用指標去接收。

#include using namespace std;

class person

person(int age, int hight)

public:

int m_age;

int *m_hight; //身高的指標

};void test01()

int main()

執行結果

**執行起來了,好像沒問題。但是這裡使用了new這個關鍵字來在堆區申請空間,這個申請是程式設計師自己控制,那麼就需要負責**記憶體,這個怎麼**,接下來,我們的析構函式就派上用場了。就是在main函式中呼叫test01, test01執行完裡面的物件都會銷毀,在銷毀之前,我們呼叫析構函式來**記憶體。

#include using namespace std;

class person

person(int age, int hight)

~person()

cout << "呼叫了person類析構函式" << endl;

}public:

int m_age;

int *m_hight; //身高的指標

};void test01()

int main()

執行的結果會報錯,

看起來,我們的**沒有問題,邏輯上說得通,為什麼會報錯。原來就是執行了這個拷貝建構函式裡面發生了問題。

分析過程:

1)開始執行test01()方法,這個方法入棧

2)執行person p, 走的有參構造

3)執行拷貝構造 person p1,這個時候p1會把p物件中身高那個指標也會拷貝過去,使用一樣的記憶體位址。

3)由於棧的特點,先進後出,所以這裡,test01()執行完是先p1物件執行銷毀操作

4)p1物件呼叫析構函式,走if判斷,判斷身高這個指標不為空,所以進行刪除和**操作。

5)p物件也要執行析構函式,也對身高指標進行判斷,由於前面是拷貝一模一樣指標,所以之前堆中記憶體已經被刪除,這次再次判斷,已經是非法操作,所以包異常斷點資訊。

通過這個例子,我們看到了淺拷貝的乙個弊端:堆區的記憶體重複釋放。

為了解決這個淺拷貝的問題,c++中使用深拷貝,就是在拷貝到堆區的指標和之前的指標位址不一樣,但是指標內資料是一樣的。

深拷貝:在堆區重新申請空間,進行拷貝操作

深拷貝的技術就是解決重複在堆區釋放記憶體的操作,就是保住每次釋放的記憶體不一樣。我們在實現拷貝建構函式裡面去實現深拷貝。

#include using namespace std;

class person

person(int age, int hight)

person(const person &p)

~person()

cout << "呼叫了person類析構函式" << endl;

}public:

int m_age;

int *m_hight; //身高的指標

};void test01()

int main()

執行結果

學完本篇,要知道,什麼是淺拷貝,什麼是深拷貝,為什麼要使用析構函式。淺拷貝就是c++編譯器採用等號賦值操作,深拷貝就是重新在堆區申請開闢乙個空間,在拷貝建構函式裡面。

總結:如果屬性有在堆區開闢的,一定要自己提供拷貝建構函式,防止淺拷貝帶來的問題。

Js 物件導向 淺拷貝和深拷貝

淺拷貝只是拷貝一層,更深層次物件級別的只拷貝引用 深拷貝拷多層,每一級別的資料都會拷貝 object.assign target,sources es6 新增方法可以淺拷貝 淺拷貝原始碼 doctype html en utf 8 viewport content width device widt...

拷貝python物件,淺拷貝和深拷貝

物件賦值實際上是簡單的物件引用。也就是說建立乙個物件然後賦值給另乙個變數的時候,python並沒有拷貝這個物件,而是拷貝了這個物件的引用。淺拷貝 淺拷貝的是物件本身,但是內容是原來物件的引用。拷貝物件本身是新的但是內容不是新的 拷貝物件的方式 來看 import copy a a b c 1,2,3...

C 物件導向程式設計(二)之 深拷貝和淺拷貝

拷貝建構函式的深淺拷貝詳解 預設拷貝建構函式可以完成物件的資料成員值簡單的複製。物件的資料資源是有指標指示的堆時,預設拷貝建構函式僅作指標值複製。而淺拷貝,在某些情況下,例如,當類的資料成員中有指標型別時,就會帶來資料安全方面的隱患,我們就需要定義乙個特定的拷貝建構函式,該拷貝建構函式不僅可以實現原...