类对象赋值(Class Assignment )和浅复制(Shallow Copy)有什么区别?

2020-06-12 09:09:15 浏览数 (2)

在SystemVerilog面向对象编程中,只有在类句柄执行new()函数之后才会创建对象,分配内存空间

代码语言:javascript复制
packet   pkt_1;pkt_1  = new();packet   pkt_2;pkt_2  = new pkt_1;

在上面的代码中,创建了pkt_2对象,其中的属性(properties)复制自pkt_1对象,这就是浅复制(shallow copy)

在浅复制过程中,给pkt_2分配了新的地址空间,然后将pkt_1中的属性赋值到pkt_2中。但是需要注意的是,浅复制中pkt_1的层次化对象(Objects)中是不会被复制的,只会复制这个层次化对象的句柄。所以,要想赋值层次化的类,需要编写定制化的复制函数执行深复制(deep copy).

从上图可以看出

代码语言:javascript复制
pkt_1  = new()

为句柄pkt_1分配了地址空间0x1234,然后其中的属性变量默认初值0

代码语言:javascript复制
pkt_1.addr = 10 ;pkt_1.data = 20 ;

为pkt_1对象中的属性变量赋值

代码语言:javascript复制
pkt_2  = new pkt_1

完成了两个工作,给对象pkt_2分配内存空间0x5678,然后将pkt_1.addr赋值给pkt_2.addr ,将pkt_1. data赋值给pkt_2. data

但是,如果packet是一个层次化的类,pkt_1对象中还存在一个底层次的address_range类对象ad_r,浅复制就存在问题了。

在上面的图片中

代码语言:javascript复制
pkt_1 = new()

分别给pkt_1和ad_r分配了地址空间0x1234和0xabcd,pkt_1.addr、pkt_1.data、pkt_1. ad_r. s_addr和pkt_1. ad_r. e_addr、默认初值都为0

在同样执行

代码语言:javascript复制
pkt_2  = new pkt_1

之后,结果就存在问题了。仿真器给pkt_2分配了新的地址空间0x5678,并且将pkt_1.addr赋值给pkt_2.addr ,将pkt_1. data赋值给pkt_2. data,但是并没有给pkt_2.ad_r分配新的地址空间,其地址空间仍然为0xabcd,也就是说pkt_2.ad_r和pkt_1.ad_r指向的是同一个地方,这就是浅复制的限制之处。

下面分别用示例展示对象赋值浅复制

对象赋值

代码语言:javascript复制
class packet;   bit[31:0] addr;  bit[31:0] data;  function new();   addr  = 32'h10;   data  = 32'hFF; endfunction   function void display();   $display("---------------------------------------------------------");   $display("t addr  =%0h",addr);   $display("t data  =%0h",data);   $display("---------------------------------------------------------");  endfunctionendclass // -- module ---module class_assignment; packet pkt_1; packet pkt_2;  initial begin   pkt_1 = new();   //creating pkt_1object   pkt_1.display();     pkt_2 =  pkt_1;   //creating pkt_2 object and assign pkt_1 topkt_2   pkt_2.display();    //changing values with pkt_2 handle   pkt_2.addr = 32'h68;   pkt_2.display();    pkt_1.display();  endendmodule

上面依次创建了pkt_1和pkt_2对象,然后将pkt_1的句柄赋值给pkt_2。可以发现pkt_2.addr的改变也改变了pkt_1.addr,因为pkt_2和pkt_1共享地址空间,也就是一样东西两个名头而已。

代码语言:javascript复制
#---------------------------------------------------------#       addr  =10#       data  =ff#---------------------------------------------------------#---------------------------------------------------------#       addr  =10#       data  =ff#---------------------------------------------------------#---------------------------------------------------------#       addr  =68#       data  =ff#---------------------------------------------------------#---------------------------------------------------------#       addr  =68#       data  =ff#---------------------------------------------------------

浅复制

代码语言:javascript复制
class address_range;  bit[31:0] s_address;  bit[31:0] e_address  ; function new();   s_address = 10;   e_address   = 50; endfunctionendclass class packet;  bit[31:0] addr;  bit[31:0] data; address_range ad_r; //class handle  function new();   addr  = 32'h10;   data  = 32'hFF;   ad_r = new(); //creating object endfunction  function void display();   $display("---------------------------------------------------------");   $display("t addr  =%0h",addr);   $display("t data  =%0h",data);   $display("t s_address  =
",ad_r.s_address);   $display("t e_address  =
",ad_r.e_address);   $display("---------------------------------------------------------"); endfunctionendclass module class_shallow_copy; packet pkt_1; packet pkt_2;  initial begin   pkt_1 = new();   //creating pkt_1object   pkt_1.display();     pkt_2 = new pkt_1;   //creatingpkt_2 object and shallow copying pkt_1 to pkt_2   pkt_2.display();    pkt_2.addr = 32'h68;   pkt_2.ad_r.s_address = 60;   pkt_2.ad_r.e_address = 80;    pkt_2.display();    pkt_1.display();  endendmodule

上面依次创建了pkt_1和pkt_2对象,然后将pkt_1的浅复制给pkt_2。可以发现pkt_2. addr的改变没有改变pkt_1.addr,pkt_2.ad_r.s_address和pkt_2.ad_r.e_address的改变也改变了pkt_1.ad_r.s_address和pkt_1.ad_r.e_address,因为pkt_2和pkt_1的低层次类对象pkt_2.ad_r和pkt_1.ad_r共享地址空间。

代码语言:javascript复制
# ---------------------------------------------------------#       addr  =10#       data  =ff#       s_address = 10#       e_address = 50#---------------------------------------------------------#---------------------------------------------------------#       addr  =10#       data  =ff#       s_address  = 10#       e_address = 50#---------------------------------------------------------#---------------------------------------------------------#       addr  =68#       data  =ff#       s_address = 60#       e_address = 80# ---------------------------------------------------------#---------------------------------------------------------#       addr  =10#       data  =ff#       s_address = 60#       e_address = 80#---------------------------------------------------------

0 人点赞