`

深浅拷贝 转载来的

 
阅读更多

一个问题, 我想这也是大家共同关心得,故解释之,看看这篇帖子,有病治病,没病亦可强身健体class A{                                                          class B{
        char store[1024];                                           char * store;
        public:                                                     public:
        A(char * input)                                              B(char * input)
      {                                                            {
         strcpy(store, input);                                       store =input;
      }                                                            }
};                                                            };
为什么以上两个类使用了不同的构造函数呢?
因为类A开辟了实在的内存空间给字符串,因此要用深拷贝进行顺序赋值,而类B只是普通的指针交换,实际上input中的内容并没有赋到store 里 。 浅拷贝有极大的危害性 虽然有人认为这很省空间。 如一下的代码 如果使用class B来运行
假设B里定义了一个成员函数Print() 来打出store里的值
void main()
{
         char input[1024]="I am Wang Xin";
         B wangxin(input);
         wangxin.Print();// 结果确实会正确地显示出 “I am Wang Xin”
        strcpy(input, "I am SB");//input的主人把input里面的字符串换成了 I am SB
         wangxin.Print();// 结果会显示出 I am SB
}
这就是浅拷贝的危害


1.        深拷贝是指源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响。举个例子,一个人名叫张三,后来用他克隆(假设法律允 许)了另外一个人,叫李四,不管是张三缺胳膊少腿还是李四缺胳膊少腿都不会影响另外一个人。比较典型的就是Value(值)对象,如预定义类型 Int32,Double,以及结构(struct),枚举(Enum)等。
考虑以下写法
        int source = int.MaxValue;//(1)初始化源对象为整数的最大值2,147,483,647
               int dest = source;//(2)赋值,内部执行深拷贝
             dest = 1024;//(3)对拷贝对象进行赋值
             source = 2048;//(4)对源对象进行赋值
      首先(2)中将source赋给dest,执行了深拷贝动作,其时dest和source的值是一样的,都是int.MaxValue;(3)对 dest进行修改,dest值变为1024,由于是深拷贝,因此不会运行source,source仍然是int.MaxValue;(4)对 source进行了修改,同样道理,dest仍然是1024,同时int.MaxValue的值也不变,仍然是2,147,483,647;只有 source变成了2048。
        再考虑以下写法
         struct Point
         {
             public int X;
             public int Y;
             public Point(int x, int y)
             {
                 X = x;
                   Y = y;
             }
         }

         Point source = new Point(10, 20);
         Point dest = source;

         dest.X = 20
      当dest.X属性变成20后,source的X属性仍然是10
2.        浅拷贝是指源对象与拷贝对象共用一份实体,仅仅是引用的变量不同(名称不同)。对其中任何一个对象的改动都会影响另外一个对象。举个例子,一个人一 开始叫张三,后来改名叫李四了,可是还是同一个人,不管是张三缺胳膊少腿还是李四缺胳膊少腿,都是这个人倒霉。比较典型的就有Reference(引用) 对象,如Class(类)。
考虑以下写法
         class Point
         {
             public int X;
             public int Y;
             public Point(int x, int y)
             {
                 X = x;
                 Y = y;
               }
         }

         Point source = new Point(10, 20);
         Point dest = source;
    dest.X = 20;
由于Point现在是引用对象,因此Point dest=source的赋值动作实际上执行的是浅拷贝,最后的结果应该是source的X字段值也变成了20。即它们引用了同一个对象,仅仅是变量明source和dest不同而已。
3.          引用对象的浅拷贝原理
引用对象之间的赋值之所以执行的是浅拷贝动作,与引用对象的特性有关,一个引用对象一般来说由两个部分组成
(1)一个具名的Handle,也就是我们所说的声明(如变量)
(2)一个内部(不具名)的对象,也就是具名Handle的内部对象。它在Manged Heap(托管堆)中分配,一般由新增引用对象的New方法是进行创建
      如果这个内部对象已被创建,那么具名的Handle就指向这个内部对象在MangedHeap中的地址,否则就是null(从某个方面来讲,如果这个具 名的handle可以被赋值为null,说明这是一个引用对象,当然不是绝对)。两个引用对象如果进行赋值,它们仅仅是复制这个内部对象的地址,内部对象 仍然是同一个,因此,源对象或拷贝对象的修改都会影响对方。这也就是浅拷贝
4.          引用对象如何进行深拷贝
由于引用对象的赋值仅仅是复制具名Handle(变量)指向的地址,因此要对引用对象进行深拷贝就要重新创建一份该对象的实例,并对该对象的字段进行逐一赋值,如以下写法
         class Point
         {
             public int X;
             public int Y;
             public Point(int x, int y)
             {
                 X = x;
                 Y = y;
             }
         }

         Point source = new Point(10, 20);
         Point dest = new Point(source.X, source.Y);
         //或以下写法
         //Point dest = new Point()
         //dest.X = source.X
    //dest.Y = source.Y
        其时,source和dest就是两个互相独立的对象了,两者的修改都不会影响对方

5.一些需要注意的东西
        (1):String字符串对象是引用对象,但是很特殊,它表现的如值对象一样,即对它进行赋值,分割,合并,并不是对原有的字符串进行操作,而是返回一个新的字符串对象
        (2):Array数组对象是引用对象,在进行赋值的时候,实际上返回的是源对象的另一份引用而已;因此如果要对数组对象进行真正的复制(深拷贝),那么需要新建一份数组对象,然后将源数组的值逐一拷贝到目的对象中

分享到:
评论

相关推荐

    08_26_C++ 深浅拷贝的区别

    08_26_C++ 深浅拷贝的区别08_26_C++ 深浅拷贝的区别08_26_C++ 深浅拷贝的区别08_26_C++ 深浅拷贝的区别08_26_C++ 深浅拷贝的区别08_26_C++ 深浅拷贝的区别08_26_C++ 深浅拷贝的区别08_26_C++ 深浅拷贝的区别08_26_...

    1.深浅拷贝.pptx

    深浅拷贝 深浅拷贝是 JavaScript 中一种常用的数据拷贝方式,分为浅拷贝和深拷贝两种。浅拷贝是指复制对象的引用,而不是复制对象本身,而深拷贝是指完全复制对象。 浅拷贝 浅拷贝是指复制对象的引用,而不是复制...

    ios中深浅拷贝的讲解

    ios中深浅拷贝的讲解,通俗移动。深浅拷贝是ios开发人员面试经常会被问到的知识点,看了本文档,相信你回答ios中的深浅拷贝有不一样的认识。

    iOS深浅拷贝例子

    在Objective-C中,实现深拷贝可以通过遵循`NSMutableCopying`协议来实现,它提供了一个`mutableCopy`方法。此方法返回一个新的可变对象,该对象是原对象的副本,并且所有嵌套的对象也都被复制。在我们的`Person`类...

    IOS深浅拷贝例子

    在iOS开发中,深拷贝和浅拷贝是Objective-C中的重要概念,主要与对象的内存管理机制有关。本文将详细解析这两个概念,...在实际开发中,应根据需求选择合适的拷贝方式,并确保实现正确的`copy`方法来确保数据的安全性。

    python 深浅拷贝与赋值

    python 深浅拷贝与赋值

    ios内存管理之深浅拷贝

    在iOS开发中,内存管理是至关重要的,尤其是对于性能敏感的应用...总之,理解深浅拷贝、`retain`和`retainCount`对于iOS开发来说是至关重要的。通过实践和测试,我们可以更好地掌握这些概念,编写出高效、稳定的代码。

    深浅拷贝和深赋值现成程序和讲解

    深浅拷贝和深赋值是两个关键的概念,它们涉及到如何正确地复制一个复杂的数据结构,如列表、字典等。这两个概念的理解对于编写高效且无副作用的代码至关重要。 深拷贝(Deep Copy)指的是创建一个新的对象,并将原...

    JavaScript基础心法 深浅拷贝(浅拷贝和深拷贝)

    说到深浅拷贝,必须先提到的是JavaScript的数据类型,之前的一篇文章JavaScript基础心法——数据类型说的很清楚了,这里就不多说了。 需要知道的就是一点:JavaScript的数据类型分为基本数据类型和引用数据类型。 ...

    详细分析JavaScript中的深浅拷贝

    在说JS中深浅拷贝之前,我们需要对JS中的数据类型有所了解,分为基本数据类型与引用数据类型,对于基本数据类型并没有深浅拷贝的说法,深浅拷贝主要针对引用数据类型。 一、浅拷贝 浅拷贝只复制了引用,并没有复制...

    深浅拷贝C++

    深浅拷贝 类的定义 C++ 源代码

    js中的深浅拷贝问题简析

    在JavaScript中,我们经常会遇到需要拷贝...总的来说,理解JavaScript中深浅拷贝的概念和区别,有助于我们编写更加健壮和高效的代码。在实际开发中,根据数据结构的复杂度和业务需求来选择合适的拷贝方式是至关重要的。

    详解iOS的深浅拷贝

    在iOS开发中,深拷贝和浅...在处理包含复杂结构的对象时,正确理解和使用深浅拷贝尤为重要,因为错误的拷贝方式可能导致意外的数据共享和逻辑错误。因此,了解并熟练掌握这两种拷贝方式对于iOS开发者来说是至关重要的。

    深浅拷贝及冷门小知识.rar

    在Python编程语言中,理解和掌握深浅拷贝的概念对于优化代码和避免潜在的错误至关重要。当我们处理复杂的对象,如列表、字典等时,拷贝操作尤为重要,因为它们涉及到内存管理。下面,我们将深入探讨赋值、深拷贝和浅...

    StrvieMeet#Python#6-2 深浅拷贝1

    一.深浅拷贝往往到了深浅拷贝的时候,就是大家最容易蒙的地方,这个比较重要为什么这么说呢,因为面试的时候必问都认真听,争取一遍就过,一般面试的时候都结合着赋值一起

    JS赋值、浅拷贝和深拷贝(数组和对象的深浅拷贝)实例详解

    本文实例讲述了JS赋值、浅拷贝和深拷贝(数组和对象的深浅拷贝)。分享给大家供大家参考,具体如下: 深拷贝和浅拷贝是只针对Object和Array这样的引用数据类型的。  浅拷贝 只是拷贝了基本类型的数据,而引用类型...

    C#深浅拷贝的深入解析

    深浅拷贝、何为深拷贝何为浅拷贝呢?我们一起来看看吧。 浅拷贝 首先我们看看浅拷贝。浅拷贝就是将对象中的所有字段复制到新对象中去,浅拷贝对于值类型和引用类型有不同的影响。值类型的值被复制到副本中后,修改...

    详解python深浅拷贝区别

    ### 详解 Python 深浅拷贝的区别 #### 前言 在 Python 编程中,对象赋值实质上是对对象引用的操作。当我们创建一个对象并将其赋值给另一个变量时,Python 并没有真正地复制这个对象,而是复制了指向该对象的引用。...

Global site tag (gtag.js) - Google Analytics