C 高階之路(三) 深拷貝和淺拷貝

2022-07-07 23:18:18 字數 2347 閱讀 8605

本文主要討論深淺拷貝的區別,如果實現。淺拷貝日常的應用比較懂,這裡不做深入討論,那麼深拷貝如何實現?目前我知道的方式有三種:反射,反序列化和表達樹的方式。這裡需要注意如果用反射來實現深拷貝的話,需要解決互相引用物件的問題。當然,反序列化就不存在這種問題了。

首先,講到深淺拷貝,自然就有乙個問題來了?什麼是深拷貝,什麼又是淺拷貝呢?下面就具體介紹下它們的定義。

深拷貝:指的是拷貝乙個物件時,不僅僅把物件的引用進行複製,還把該物件引用的值也一起拷貝。這樣進行深拷貝後的拷貝物件就和源物件互相獨立,其中任何乙個物件的改動都不會對另外乙個物件造成影響。舉個例子,乙個人叫張三,然後使用轉殖技術以張三來轉殖另外乙個人叫李四,這樣張三和李四就是相互獨立的,不管張三缺胳膊還是李四少腿了都不會影響另外乙個人。在.net領域,值物件就是典型的例子,如int, double以及結構體和列舉等。具體例子如下所示:

int source = 123;

// 值型別賦值內部執行深拷貝

int copy =source;

// 對拷貝物件進行賦值不會改變源物件的值

copy = 234;

// 同樣對源物件賦值也不會改變拷貝物件的值

source = 345;

淺拷貝:指的是拷貝乙個物件時,僅僅拷貝物件的引用進行拷貝,但是拷貝物件和源物件還是引用同乙份實體。此時,其中乙個物件的改變都會影響到另乙個物件。例如,乙個人一開始叫張三,後來改名字為張老三了,可是他們還是同乙個人,不管張三缺胳膊還是張老三少腿,都反應在同乙個人身上。在.net中引用型別就是乙個例子。如類型別。具體例子如下所示:

public

class

person}

class

program

; person copyp = sourcep; //

淺拷貝 copyp.name = "

張老三"; //

拷貝物件改變name值

//結果都是"張老三",因為實現的是淺拷貝,乙個物件的改變都會影響到另乙個物件

console.writeline("

person.name: [sourcep: ] [copyp:]

", sourcep.name, copyp.name);

console.read();

}}

這裡淺拷貝的實現比較容易,所以就不做介紹了。主要討論下實現深拷貝的方式

我比較常用的方式是使用newtonsoft的json。

t ss= jsonconvert.deserializeobject(jsonconvert.serializeobject(s));

當然還有很多其他的方式,比如下面

//

利用xml序列化和反序列化實現

public

static t deepcopywithxmlserializer(t obj)

return

(t)retval;

}

//

利用二進位制序列化和反序列實現

public

static t deepcopywithbinaryserialize(t obj)

return

(t)retval;

}

//

利用datacontractserializer序列化和反序列化實現

public

static t deepcopy(t obj)

return

(t)retval;

}

廢話不多說,直接上**

public

static t deepcopywithreflection(t obj)

return

(t)convert.changetype(copied, obj.gettype());

}//獲取返回值例項

object retval =activator.createinstance(obj.gettype());

//獲取所有型別的屬性

propertyinfo properties =obj.gettype().getproperties(

bindingflags.public |bindingflags.nonpublic

| bindingflags.instance |bindingflags.static);

//賦值

foreach (var property in

properties)

return

(t)retval;

}

這個會在後面的一篇專門介紹表示式樹的文章裡詳細介紹。

C 淺拷貝和深拷貝

class test test const test t val new int t.val test private int val 現在定義兩個物件,test t1 9 test t2 t1 如果你不提供copy建構函式 注釋掉的那個 那麼t1和t2的成員 val指向同乙個物件,當析構的時候,同...

c 深拷貝和淺拷貝

深拷貝和淺拷貝 ca const ca c 就是我們自定義的拷貝建構函式。可見,拷貝建構函式是一種特別的建構函式,函式的名稱必須和類名稱一致,他的唯一的乙個引數是本型別的乙個引用變數,該引數是const型別,不可變的。例如 類x的拷貝建構函式的形式為x x x 當用乙個已初始化過了的自定義類型別物件...

c 深拷貝和淺拷貝

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