zoukankan      html  css  js  c++  java
  • 关于复制

    深复制vs.浅复制

    • 浅复制:复制中把成员指针变量当成“指针”处理,赋值后两个指针指向相同的内存
    • 深复制:复制中把指针成员变量当成“值”处理,赋值后指针指向对象副本(即两个指针指向的内存不同,但内存中内容相同)

    C++中的复制

    C++中的指针具有缺陷,无法保证指针指向的空间可用(C++从入门到段错误~~)当指针作为类成员时,应进行恰当的管理,

    1. 指针成员采取常规指针型行为。这样的类具有指针的所有缺陷但无需特殊的复制控制。
    2. 类可以实现所谓的“智能指针”行为。指针所指向的对象是共享的,但类能够防止悬垂指针。
    3. 类采取值型行为。指针所指向的对象是唯一的,由每个类对象独立管理。

    tip

    • 为了管理具有指针成员的类,必须定义三个复制控制成员:复制构造函数、赋值操作符和析构函数。这些成员可以定义指针成员的指针型行为或值型行为,也就是决定了复制的时候是深复制还是浅复制

    OC的复制

    集合的复制

    不可变集合

    • copy:指针复制。cpy_arr == ori_arr
    • mutableCopy:对象复制(单层深复制,对集合中的元素进行指针复制)
    • initWithArray:copyItems:YES
      • 当集合元素可变时,对该元素进行对象复制;否则进行指针复制
      • 返回__NSArrayI *
    • arrayWithArray对集合进行对象复制,对集合内元素进行指针复制

    可变集合

    • copy:对象复制cpy_arr != ori_arr
    • mutableCopy:对象复制(单层深复制,对集合中的元素进行指针复制)
    • initWithArray:copyItems:YES当元素为可变时,复制该元素,不可变时,不复制
      • 返回__NSArrayI *
      • 当集合元素可变时,对该元素进行对象复制;否则进行指针复制
    • arrayWithArray对集合进行对象复制,对集合内元素进行指针复制 ###非集合对象 参考集合的复制(毕竟对象的实例变量也有可能是指针),主要考虑对象是否可变

    tip

    • 对于二维数组,即便使用initWithArray:copyItems:YES,对于数组的元素,也只是进行指针复制,亦即:
      • arr_cpy != arr
      • arr_cpy[i] != arr[i]
      • arr_cpy[i][j] == arr[i][j]
    • 若想完全实现深复制,可通过NSKeyedArchiverNSKeyedUnarchiver实现

    Swift中的复制

    • Swift中的字符串,数组,字典类型作为结构体被实现
    • 当他们被赋值给一个新的常量/变量,或者作为实参被传递给函数或方法是,将被复制
    • Swift内部管理所有的副本确保整体性能得到优化

    pyhton中的复制

    • 对对象赋值时,进行指针复制
    aList=[[1, 2], 3, 4] 
    b = a
    #id(b) == id(a)
    
    • 切片,对所指指定的元素进行指针复制。
    aList=[[1, 2], 3, 4]
    b = aList[:]
    #id(b) != id(a)
    #id(b[0]) == id(a[0])
    
    • copy.copy 只拷贝父对象,不会拷贝对象的内部的子对象。
    aList=[[1, 2], 3, 4]
    b = copy.copy(aList)
    #id(b) != id(a)
    #id(b[0]) == id(a[0])
    
    • copy.deepcopy 拷贝对象及其子对象
    aList=[[1, 2], 3, 4]
    b = copy.copy(aList)
    #id(b) != id(a)
    #id(b[0]) != id(a[0])
    

    C#中的复制

    MemberwiseClone

    • MemberwiseClone 方法创建一个浅表副本
    • 具体来说就是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象

    实现完全深复制

    • 借助.Net的序列化和反序列化机制,可以十分简单的深度Clone一个对象。
    • 首先将对象序列化到内存流中,此时对象和对象引用的所用对象的状态都被保存到内存中。.Net的序列化机制会自动处理循环引用的情况。
    • 然后将内存流中的状态信息反序列化到一个新的对象中。
  • 相关阅读:
    汉化DevExpress
    《苹果往事》的台式翻译
    说说《程序员》杂志的排版
    关于量化考核绩效
    as3 浅复制 深复制
    斜视角的讨论(转)
    斜角地图原理解释及斜角图形绘制实例细述(转)
    垃圾回收测试
    Flash务实主义(八)——减少数据传输量(转)
    翻译]游戏主循环
  • 原文地址:https://www.cnblogs.com/rainySue/p/guan-yu-fu-zhi.html
Copyright © 2011-2022 走看看