對於基本型別資料以及簡單的物件,它們的拷貝比較簡單,就是直接複製記憶體。比如下面的**:
class base
base(int a, int b): m_a(a), m_b(b)
private:
int m_a;
int m_b;
};int main()
b 和 obj2 都是以拷貝的方式初始化的,具體來說,就是將 a 和 obj1 所在記憶體中的資料按照二進位制位(bit)複製到 b 和 obj2 所在的記憶體,這種預設的拷貝行為就是淺拷貝,這和呼叫memcpy() 很類似。但是,當類的成員包含指標的時候,使用淺拷貝就不能滿足實際要求了,來看下面的例子。
#include #includeusing namespace std;
class people
;people::people(string name, int* ptr)
people::~people()
void people::display()
void people::setage(int age)
int main()
/*輸出:
xiao ming is age 10
xiao ming is age 10
xiao ming is age 15
xiao ming is age 15 //修改 people1 age 之後 people2 age 也被修改了
*/
看上面的例子修改 people1 age 之後 people2 age 也被修改了
,這是因為mp_age
是乙個指標,裡面存放的是指向儲存 age 內容的位址,使用預設拷貝建構函式時這是把 people1的 mp_age指標裡存放的位址賦值給了people2的mp_age指標導致兩個指標指向了同一塊記憶體空間,這時候預設拷貝建構函式的不足就體現出來了。
對於簡單的類,預設的拷貝建構函式一般就夠用了,我們也沒有必要再顯式地定義乙個功能類似的拷貝建構函式。但是當類持有其它資源時,例如動態分配的記憶體、指向其他資料的指標等,預設的拷貝建構函式就不能拷貝這些資源了,我們必須顯式地定義拷貝建構函式,以完整地拷貝物件的所有資料。下面我們顯示定義乙個拷貝建構函式來彌補預設拷貝建構函式的不足,**如下:
#include #includeusing namespace std;
class people
;people::people(string name, int* ptr)
people::people(const people &peo)
people::~people()
void people::display()
void people::setage(int age)
int main()
/*輸出:
xiao ming is age 10
xiao ming is age 10
xiao ming is age 15
xiao ming is age 10 //修改 people1 age 之後 people2 age 沒有被修改
*/
我們顯式地定義了拷貝建構函式,它除了會將原有物件的所有成員變數拷貝給新物件,還會為新物件再分配一塊記憶體,並將原有物件所持有的記憶體也拷貝過來。這樣做的結果是,原有物件和新物件所持有的動態記憶體是相互獨立的,更改乙個物件的資料不會影響另外乙個物件。
這種將物件所持有的其它資源一起拷貝的行為叫做深拷貝,必須顯示的定義拷貝建構函式才能達到深拷貝的目的。
如果乙個類擁有指標型別的成員變數,那麼絕大部分情況下就需要深拷貝,因為只有這樣,才能將指標指向的內容再複製出乙份來,讓原有物件和新生物件相互獨立,彼此之間不受影響。如果類的成員變數沒有指標,一般淺拷貝就能滿足要求。另外一種需要深拷貝的情況就是在建立物件時進行一些預處理工作。
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 ...