• 2.deep copy与 shallow copy 区别


    写在前面

    1.   浅拷贝可以使用列表自带的copy()函数(如list.copy()),或者使用copy模块的copy()函数。深拷贝只能使用copy模块的deep copy(),所以使用前要导入:from copy import deepcopy

    2.   如果拷贝的对象里的元素只有值,没有引用,那浅拷贝深拷贝没有差别,都会将原有对象复制一份,产生一个新对象,对新对象里的值进行修改不会影响原有对象,新对象和原对象完全分离开。

    3.   如果拷贝的对象里的元素包含引用(像一个列表里储存着另一个列表,存的就是另一个列表的引用),那浅拷贝和深拷贝是不同的,浅拷贝虽然将原有对象复制一份,但是依然保存的是引用,所以对新对象里的引用里的值进行修改,依然会改变原对象里的列表的值,新对象和原对象完全分离开并没有完全分离开。而深拷贝则不同,它会将原对象里的引用也新创建一个,即新建一个列表,然后放的是新列表的引用,这样就可以将新对象和原对象完全分离开。

    在SV中经常用到的copy主要有三种:句柄copy,深copy和浅copy; 

    句柄复制
    只复制句柄,相当于两个句柄指向同一个对象,永远都只有一个对象

    handle copy 代码: 

    1. class A;
    2. int j=5;
    3. endclass
    4. class B;
    5. int i=3;
    6. A a=new;
    7. endclass
    8. program example;
    9. initial begin
    10. B b1=new;
    11. B b2;//重点注意句柄的声明必须都在前面,new可以在任意位置
    12. b1.i=11;
    13. b1.a.j=22;
    14. $display("====b1 initialization====");
    15. $display("i=%0d",b1.i);
    16. $display("j=%0d",b1.a.j);
    17. b2=new;
    18. b2.i=33;
    19. b2.a.j=44;
    20. $display("====b1 initialization====");
    21. $display("i=%0d",b2.i);
    22. $display("j=%0d",b2.a.j);
    23. b2=b1;
    24. $display("====b2 copy b1 handle====");
    25. $display("i=%0d",b2.i);
    26. $display("j=%0d",b2.a.j);
    27. end
    28. endprogram

    handle copy 仿真结果:

    b2 copy b1的句柄 ,两个句柄都指向b1的对象,所显示的内容是一样的。

    ================================================================= 

    浅拷贝:

    浅拷贝时,只copy成员变量的句柄,而不会拷贝句柄所指向的对象中的内容;

    shallow copy代码:

    1. class A;
    2. int j=5;
    3. endclass
    4. class B;
    5. int i=3;
    6. A a=new;
    7. endclass
    8. //shallow copy
    9. program example;
    10. initial begin
    11. B b1=new;
    12. B b2;//重点注意句柄的声明必须都在前面,new可以在任意位置
    13. b1.i=11;
    14. b1.a.j=22;
    15. $display("====b1 initialization====");
    16. $display("i=%0d",b1.i);
    17. $display("j=%0d",b1.a.j);
    18. b2=new b1;
    19. b2.i=33;
    20. b2.a.j=44;
    21. $display("====b2 shallow copy b1====");
    22. $display("i=%0d",b1.i);
    23. $display("j=%0d",b1.a.j);
    24. $display("i=%0d",b2.i);
    25. $display("j=%0d",b2.a.j);
    26. end
    27. endprogram

    shallow copy 仿真结果: 

     

    很明显,更改了b2句柄指向的B中的i,和b2句柄指向的B中a句柄指向的对象的元素j。
    最后b1中的i没有发生任何变化。但是b1对象a的j也跟着b2变化。 

    =============================================================== 

    深拷贝

    深拷贝时,不仅仅会拷贝当前的对象的成员变量,还会拷贝实例中的句柄的对象内容,即进行深层次的复制  

    deep copy 代码:

    1. class A;
    2. int j=5;
    3. endclass
    4. class B;
    5. int i=3;
    6. A a=new;
    7. function deep_copy(B temp);
    8. this.i=temp.i;
    9. this.a.j=temp.a.j;
    10. endfunction
    11. endclass
    12. //deep copy
    13. program example;
    14. initial begin
    15. B b1=new;
    16. B b2=new;//重点注意句柄的声明必须都在前面,new可以在任意位置
    17. b1.i=11;
    18. b1.a.j=22;
    19. $display("====b1 initialization====");
    20. $display("i=%0d",b1.i);
    21. $display("j=%0d",b1.a.j);
    22. b2.deep_copy(b1) ;
    23. b2.i=33;
    24. b2.a.j=44;
    25. $display("====b2 deep copy b1====");
    26. $display("i=%0d",b1.i);
    27. $display("j=%0d",b1.a.j);
    28. $display("i=%0d",b2.i);
    29. $display("j=%0d",b2.a.j);
    30. end
    31. endprogram

     deep copy仿真结果:

     深拷贝需要自己定义

    更改了b2句柄指向的B中的i,和b2句柄指向的B中a句柄指向的对象的元素j。
    最后b1中的i和b1对象a的j没有发生任何变化。

     

  • 相关阅读:
    【Java实战】工作中如何规范定义Java常量
    516. 最长回文子序列
    Qt存手撸界面
    安培龙冲刺创业板上市:收入依赖美的,邬若军、黎莉夫妇为实控人
    虚拟机无法启动提示give root password for maintenance的多种解决方法
    别再问我Python打包成exe了!(终极版)
    django+drf+vue 简单系统搭建 (2) - drf 应用
    MongoDB快速上手
    JavaSE之List中ArrayList底层和LinkedList底层
    centos7安装nacos2.1.0
  • 原文地址:https://blog.csdn.net/weixin_45680021/article/details/126456440