正確實現淺拷貝和深拷貝

2021-12-29 23:16:28 字數 1636 閱讀 6496

淺拷貝和深拷貝的區別:

淺拷貝:

修改副本的值型別字段不會影響源物件對應的字段,修改副本的引用型別欄位會影響源物件,因為源物件複製給副本物件的時候,是引用型別的引用位址,也就是兩者引用的是同乙個物件。

深拷貝:

無論值型別還是引用型別的字段,修改副本物件不會影響源物件,即使是引用型別,也是重新建立了乙個新的物件引用。

要想自定義型別具有clone拷貝的能力,就得繼承icloneable介面,然後根據需求,實現clone方法以便實現淺拷貝或者深拷貝。

淺拷貝示例:

複製**

namespace webapplication

public int age

public department department

//實現icloneable介面成員

public object clone()

}public class department

public override string tostring()

}public partial class webform1 : system.web.ui.page

};//從employeea 淺拷貝出 employeeb

employee employeeb = employeea.clone() as employee;

//修改employeeb物件的屬性

employeea.idcode = "b";

employeea.age = 15;

employeea.department.name = "departmentb";

//輸出以便驗證

response.write(employeeb.idcode); // a 

response.write(employeeb.age);    //10

response.write(employeeb.department.tostring()); //departmentb}}

}複製**

從輸出結果可以驗證得到結果:

1、idcode即使是string引用型別,object.memberwiseclone 依然為其創造了副本,在淺拷貝中,我們可以將string當做值型別來看待。

2、employee的department屬性是引用型別,改變源物件employeea中的值,會影響到副本物件employeeb

深拷貝示例

建議使用序列化的形式進行深拷貝:

複製**

//實現icloneable介面成員

public object clone()

}複製**

這裡我按照書中的**來執行程式,結果爆黃頁錯誤了,提示資訊是:

中的型別「webapplication.employee」未標記為可序列化。

因為之前有相關的開發經驗,知道那是因為實體類沒有被標記為序列化屬性,難道作者編寫示例的時候沒有檢查出這個錯誤?或者是其他原因?

我們在實體類上標記一下即可執行成功,這是修改源物件employeea中的值也不會影響到副本物件employeeb了。

[serializable]

public class employee : icloneable

[serializable]

public class department

正確實現淺拷貝和深拷貝

為物件建立副本的技術稱為拷貝 也叫轉殖 我們將拷貝分為淺拷貝和深拷貝。淺拷貝 將物件中的所有字段複製到新的物件 副本 中。其中,值型別欄位的值被複製到副本中後,在副本中的修改不會影響到源物件對應的值。而引用型別的字段被複製到副本中的是引用型別的引用,而不是引用的物件,在副本中對引用型別的字段值做修改...

深拷貝和淺拷貝

淺拷貝就是物件的資料成員之間的簡單賦值,如你設計了乙個沒有類而沒有提供它的複製建構函式,當用該類的乙個物件去給令乙個物件賦值時所執行的過程就是淺拷貝,如 class a a private int data int main 這一句b a 就是淺拷貝,執行完這句後b.data 5 如果物件中沒有其他...

淺拷貝和深拷貝

以下情況都會呼叫拷貝建構函式 乙個物件以值傳遞的方式傳入函式體 例如 已知class a,class b void func a a void func a a func b b 此時函式對b的操作是呼叫拷貝建構函式後的臨時拷貝物件。多數傳指標 乙個物件以值傳遞的方式從函式返回 如 return b...