zoukankan      html  css  js  c++  java
  • 深拷贝和浅拷贝(一)

    1. 浅拷贝

        所谓浅拷贝,指的是在对象复制时,只对对象的数据成员进行复制,但是遇到有动态成员如指针时就会出问题。

    [c-sharp] view plain copy
     
    1. class Rect  
    2. {  
    3. public:  
    4.     Rect()      // 构造函数,p指向堆中分配的一空间  
    5.     {  
    6.         p = new int(100);  
    7.     }  
    8.     ~Rect()     // 析构函数,释放动态分配的空间  
    9.     {  
    10.         if(p != NULL)  
    11.         {  
    12.             delete p;  
    13.         }  
    14.     }  
    15. private:  
    16.     int width;  
    17.     int height;  
    18.     int *p;     // 一指针成员  
    19. };  
    20.   
    21. int main()  
    22. {  
    23.     Rect rect1;  
    24.     Rect rect2(rect1);   // 复制对象  
    25.     return 0;  
    26. }  

        在这段代码运行结束之前,会出现一个运行错误。原因就在于在进行对象复制时,对于动态分配的内容没有进行正确的操作。我们来分析一下:

        在运行定义rect1对象后,由于在构造函数中有一个动态分配的语句,因此执行后的内存情况大致如下:

     

     

        在使用rect1复制rect2时,由于执行的是浅拷贝,只是将成员的值进行赋值,这时 rect1.p= rect2.p,也即这两个指针指向了堆里的同一个空间,如下图所示:

    在销毁对象时,两个对象的析构函数将对同一个内存空间释放两次。我们需要的不是两个p有相同的值,而是两个p指向的空间有相同的值,解决办法就是使用“深拷贝”。


    3. 深拷贝

        在“深拷贝”的情况下,对于对象中动态成员,就不能仅仅简单地赋值了,而应该重新动态分配空间,如上面的例子就应该按照如下的方式进行处理:

    [c-sharp] view plain copy
     
    1. class Rect  
    2. {  
    3. public:  
    4.     Rect()      // 构造函数,p指向堆中分配的一空间  
    5.     {  
    6.         p = new int(100);  
    7.     }  
    8.     Rect(const Rect& r)  
    9.     {  
    10.         width = r.width;  
    11.         height = r.height;  
    12.         p = new int;    // 为新对象重新动态分配空间  
    13.         *p = *(r.p);  
    14.     }  
    15.     ~Rect()     // 析构函数,释放动态分配的空间  
    16.     {  
    17.         if(p != NULL)  
    18.         {  
    19.             delete p;  
    20.         }  
    21.     }  
    22. private:  
    23.     int width;  
    24.     int height;  
    25.     int *p;     // 一指针成员  
    26. };  

    此时,在完成对象的复制后,内存的一个大致情况如下:

     

    此时rect1的p和rect2的p各自指向一段内存空间,但它们指向的空间具有相同的内容,这就是所谓的“深拷贝”。

     

  • 相关阅读:
    常见HTTP状态码(200、301、302、500等)解说
    HTTP协议详解(真的很经典)
    计算机网络基础知识总结
    js调试中打印语句
    关于函数return的一些理解与小实例
    网站的导航菜单 远择一个栏目跳转后,为导航菜单的这个栏目增加选中的样式的思路
    alias记录
    利用vue-cli配合vue-router搭建一个完整的spa流程
    node+vue-cli+webpack搭建教程
    nodejs参考文章
  • 原文地址:https://www.cnblogs.com/zzdbullet/p/9949749.html
Copyright © 2011-2022 走看看