C class 淺拷貝 與 深拷貝

2022-01-29 12:46:25 字數 2031 閱讀 8372

memberwiseclone 方法建立乙個淺表副本,具體來說就是建立乙個新物件,然後將當前物件的非靜態字段複製到該新物件。

如果欄位是值型別的,則對該字段執行逐位複製。如果欄位是引用型別,則複製引用但不複製引用的物件;因此,原始物件及其複本引用同一物件。

為了實現深度複製,我們就必須遍歷有相互引用的物件構成的圖,並需要處理其中的迴圈引用結構。這無疑是十分複雜的。幸好借助.net的序列化和反序 列化機制,可以十分簡單的深度clone乙個物件。原理很簡單,首先將物件序列化到記憶體流中,此時物件和物件引用的所用物件的狀態都被儲存到記憶體 中。.net的序列化機制會自動處理迴圈引用的情況。然後將記憶體流中的狀態資訊反序列化到乙個新的物件中。這樣乙個物件的深度複製就完成了。在原型設計模 式中clone技術非常關鍵。

下面的**就是演示這個問題:

using system;

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();}}}

另外乙個例子是針對陣列,c#中的陣列是引用型的變數,我們通過陣列來進行演示: 

淺拷貝

using system;

class shallowcopy : icloneable

;public object clone()

public void display()

}class client

}

shallowcopy物件實現了乙個淺拷貝,因此當對sc1進行轉殖時,其欄位v並沒有轉殖,這導致sc1與sc2的字段v都指向了同乙個v,因此,當修改了sc1的v[0]後,sc2的v[0]也發生了變化。

深拷貝:

using system;

class deepcopy : icloneable

;// 預設建構函式

public deepcopy()

// 供clone方法呼叫的私有建構函式

private deepcopy(int v)

public object clone()

public void display()

}class client

}

這次在轉殖的時候,不但轉殖物件本身,連裡面的陣列字段一併轉殖。因此,最終列印出來的dc1與dc2不同。

當然我們也可以建個深拷貝的幫助類:

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...