memberwiseclone 方法建立乙個淺表副本,具體來說就是建立乙個新物件,然後將當前物件的非靜態字段複製到該新物件。為了實現深度複製,我們就必須遍歷有相互引用的物件構成的圖,並需要處理其中的迴圈引用結構。這無疑是十分複雜的。幸好借助.net的序列化和反序 列化機制,可以十分簡單的深度clone乙個物件。原理很簡單,首先將物件序列化到記憶體流中,此時物件和物件引用的所用物件的狀態都被儲存到記憶體 中。.net的序列化機制會自動處理迴圈引用的情況。然後將記憶體流中的狀態資訊反序列化到乙個新的物件中。這樣乙個物件的深度複製就完成了。在原型設計模 式中clone技術非常關鍵。如果欄位是值型別的,則對該字段執行逐位複製。如果欄位是引用型別,則複製引用但不複製引用的物件;因此,原始物件及其複本引用同一物件。
下面的**就是演示這個問題:
using system;另外乙個例子是針對陣列,c#中的陣列是引用型的變數,我們通過陣列來進行演示:using system.io;
using system.runtime.serialization.formatters.binary;
namespace clonedemo;
public democlass clone1() //淺clone
public democlass clone2() //深clone
} class program
; democlass b = a.clone1();
democlass c = a.clone2();
// 更改 a 物件的iarr[0], 導致 b 物件的iarr[0] 也發生了變化 而 c不會變化
a.iarr[0] = 88;
console.writeline("memberwiseclone");
console.writeline(b.i);
foreach (var item in b.iarr)
console.writeline("clone2");
console.writeline(c.i);
foreach (var item in c.iarr)
console.readline();}}}
淺拷貝
using system;shallowcopy物件實現了乙個淺拷貝,因此當對sc1進行轉殖時,其欄位v並沒有轉殖,這導致sc1與sc2的字段v都指向了同乙個v,因此,當修改了sc1的v[0]後,sc2的v[0]也發生了變化。class shallowcopy : icloneable
;public object clone()
public void display()
}class client
}
深拷貝:
using system;這次在轉殖的時候,不但轉殖物件本身,連裡面的陣列字段一併轉殖。因此,最終列印出來的dc1與dc2不同。class deepcopy : icloneable
;// 預設建構函式
public deepcopy()
// 供clone方法呼叫的私有建構函式
private deepcopy(int v)
public object clone()
public void display()
}class client
}
當然我們也可以建個深拷貝的幫助類:
public static class objectcopier**:// don't serialize a null object, simply return the default for that object
if (object.referenceequals(source, null))
iformatter formatter = new binaryformatter();
stream stream = new memorystream();
using (stream)
}}
「淺拷貝」與「深拷貝」
c 中物件的複製就如同 轉殖 用乙個已有的物件快速地複製出多個完全相同的物件。一般而言,以下三種情況都會使用到物件的複製 1 建立乙個新物件,並用另乙個同類的已有物件對新物件進行初始化,例如 cpp view plain copy class rect rect rect1 rect rect2 r...
淺拷貝與深拷貝
淺拷貝 1 2 myclass a,b a b 為了封裝性和解耦,同型別的兩個物件之間進行賦值操作時,所有成員變數被複製,包括私有成員 指標變數。類的成員函式在傳遞或返回物件時都會進行物件複製產生臨時物件,比如函式呼叫時實參變為形參,以及函式返回物件。考慮到效能和使用者要求不同,編譯器不複製物件內部...
「淺拷貝」與「深拷貝」
c 中物件的複製就如同 轉殖 用乙個已有的物件快速地複製出多個完全相同的物件。一般而言,以下三種情況都會使用到物件的複製 1 建立乙個新物件,並用另乙個同類的已有物件對新物件進行初始化,例如 cpp view plain copy class rect rect rect1 rect rect2 r...