本文主要討論深淺拷貝的區別,如果實現。淺拷貝日常的應用比較懂,這裡不做深入討論,那麼深拷貝如何實現?目前我知道的方式有三種:反射,反序列化和表達樹的方式。這裡需要注意如果用反射來實現深拷貝的話,需要解決互相引用物件的問題。當然,反序列化就不存在這種問題了。
首先,講到深淺拷貝,自然就有乙個問題來了?什麼是深拷貝,什麼又是淺拷貝呢?下面就具體介紹下它們的定義。
深拷貝:指的是拷貝乙個物件時,不僅僅把物件的引用進行複製,還把該物件引用的值也一起拷貝。這樣進行深拷貝後的拷貝物件就和源物件互相獨立,其中任何乙個物件的改動都不會對另外乙個物件造成影響。舉個例子,乙個人叫張三,然後使用轉殖技術以張三來轉殖另外乙個人叫李四,這樣張三和李四就是相互獨立的,不管張三缺胳膊還是李四少腿了都不會影響另外乙個人。在.net領域,值物件就是典型的例子,如int, double以及結構體和列舉等。具體例子如下所示:
int source = 123;// 值型別賦值內部執行深拷貝
int copy =source;
// 對拷貝物件進行賦值不會改變源物件的值
copy = 234;
// 同樣對源物件賦值也不會改變拷貝物件的值
source = 345;
淺拷貝:指的是拷貝乙個物件時,僅僅拷貝物件的引用進行拷貝,但是拷貝物件和源物件還是引用同乙份實體。此時,其中乙個物件的改變都會影響到另乙個物件。例如,乙個人一開始叫張三,後來改名字為張老三了,可是他們還是同乙個人,不管張三缺胳膊還是張老三少腿,都反應在同乙個人身上。在.net中引用型別就是乙個例子。如類型別。具體例子如下所示:
publicclass
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;
}
廢話不多說,直接上**
publicstatic 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 ...