C 深拷貝與淺拷貝

2021-07-03 02:27:34 字數 2119 閱讀 9660

**:

對於普通型別的物件來說,它們之間的複製是很簡單的,例如:

int a=88;

int b=a; 

而類物件與普通物件不同,類物件內部結構一般較為複雜,存在各種成員變數。下面看乙個類物件拷貝的簡單例子。

#include using namespace std;

class cexample

void show ()

cexample(const cexample& c)

void show ()

ca(const ca& c)

void show()

;#endif

cperson.cpp

#include"cperson.h"

#includecperson::cperson(int age):m_age(age)

void cperson::print(void)

執行結果:

my age is 10

my age is 10

結果分析:

對於語句cperson jim(tom),我們並沒有定義相應的拷貝建構函式,編譯器將會自動生成乙個預設的拷貝建構函式。

預設拷貝建構函式所做的工作是,將乙個物件的全部資料成員賦值給另乙個物件的資料成員。

c++把只物件資料成員簡單賦值這種情況稱為「淺拷貝」。

聽起來,編譯器似乎很好,會提供乙個我們沒有定義的拷貝建構函式,但這後面存在巨大的風險。

所以有些事情(拷貝建構函式)還是自力更生不接受外援的好。

在接下來的example 2中,我們將看到淺拷貝帶來的錯誤

有錯誤的淺拷貝

cperson.h

#ifndef _cperson_h

#define _cperson_h

class cperson

;#endif

cperson.cpp

#include"cperson.h"

#include#includecperson::cperson(int age,char *name)

m_age = age;

coutcperson::~cperson()

結果分析:

可以看到,程式出現了錯誤。

在執行語句cperson tom(10,「tom」)時,用new動態開闢了一段記憶體,用來存放」tom」。

在執行cperson jim(tom)時,只是將tom的成員(tom.m_age,tom.m_name)賦值給jim相應的成員。

此時,tom.m_name和jim.m_name指向同一記憶體空間,然而,系統並沒給jim.m_name開闢相應的記憶體空間。

執行完jim.print()後,開始執行析構函式,析構函式的執行順序和物件建構函式的執行順尋相反,所以先執行jim的析構函式,執行完jim的析構函式後,jim.m_name所指的記憶體空間已經釋放。接著執行tom的析構函式,此時就會出現問題,即在釋放tom.m_name所指的記憶體空間時會出現問題,因為這段記憶體空間在jim的析構函式中已經釋放過了。

出現這種原因的根本在於「淺拷貝」,所以需要定義自己的建構函式。

深拷貝

接下來看example 3,在該例子中執行深拷貝。

cperson.h

#ifndef _cperson_h

#define _cperson_h

class cperson

;#endif

cperson.cpp

#include"cperson.h"

#include#includecperson::cperson(int age,char *name)

m_age = age;

cout#include"cperson.h"

#includevoid main(void)

可以看到,自己定義了拷貝建構函式後,就沒有問題了.在實際中應該避免淺拷貝。

C 深拷貝 與 淺拷貝

最近在寫一些c 程式,遇到個問題,記憶體會出錯,查了一些材料,終於發現問題所在了,原來碰到了傳說中的深拷貝和淺拷貝問題了,檢視一些材料,現在對這個問題做個總結 在類定義中,預設是淺拷貝,即 位拷貝 用在基本類中或者一些沒有指標的自定義型別中沒有一點問題,但是當遇到含有指標變數的自定義型別的時候,就會...

C 淺拷貝與深拷貝

淺拷貝 shallow copy 指的是當物件的字段被拷貝的時候,字段應用的物件不會被拷貝。深拷貝是對物件例項當中的字段引用的物件也進行拷貝的一種方式。淺拷貝可以通過將類實現介面icloneable class myclass icloneable 舉個簡單的例項 using system usin...

c 深拷貝與淺拷貝

對於普通型別的物件來說,它們之間的複製是很簡單的,例如 int a 88 int b a 而類物件與普通物件不同,類物件內部結構一般較為複雜,存在各種成員變數。下面看乙個類物件拷貝的簡單例子。iostream using namespace std class cexample void show ...