对象拷贝

1.对象拷贝

1.1 浅拷贝

当pkt与新对象new objects的构造函数new()一起使用时,pkt中的内容将被复制到pkt2中。

Packet pkt, pkt2;
pkt = new;
pkt2 = new pkt;

这种方法称为浅拷贝,因为所有变量都跨整数、字符串、实例句柄等进行复制,但嵌套对象并未完全复制。只有它们的句柄将分配给新对象,因此两个packet都将指向同一个嵌套对象实例。为了说明这一点,让我们看一个例子.

class Header;
int id;
function new (int id);
this.id = id;
endfunction
function showId();
$display ("id=0x%0d", id);
endfunction
endclass
 
class Packet;
int addr;
int data;
Header hdr;
function new (int addr, int data, int id);
hdr = new (id);
this.addr = addr;
this.data = data;
endfunction
function display (string name);
$display ("[%s] addr=0x%0h data=0x%0h id=%0d", name, addr, data, hdr.id);
endfunction
endclass
module tb;
Packet p1, p2;
initial begin
// Create a new pkt object called p1
p1 = new (32'hface_cafe, 32'h1234_5678, 26);
p1.display ("p1");
// Shallow copy p1 into p2; p2 is a new object with contents in p1
p2 = new p1;
p2.display ("p2");
// Now let's change the addr and id in p1
p1.addr = 32'habcd_ef12;
p1.data = 32'h5a5a_5a5a;
p1.hdr.id = 17;
p1.display ("p1");
// Print p2 and see that hdr.id points to the hdr in p1, while addr and data remain unchanged.
p2.display ("p2");
end
endmodule

类Packet包含一个名为Header的嵌套类。首先,我们创建了一个名为p1的数据包并为其分 配了一些值。然后使用浅拷贝方法将p2创建为p1的副本。为了证明只复制句柄而不是整个对 象,修改了p1数据包的成员,包括嵌套类中的成员。当打印p2中的内容时,我们可以看到嵌 套类中的id成员保持不变。

这是一种简易复制(shallow copy),原对象的值被盲目copy到对象中,如果类A1中包含一个指向另一个子类B的句柄,那么复制类A2中只是复制了子类B的句柄,A1和A2中的B对象指向的是同一个对象。

1.2 深拷贝

深拷贝是复制所有内容(包括嵌套对象)的地方,通常需要自定义代码来实现此目的。

Packet p1 = new;
Packet p2 = new;
p2.copy (p1);

让我们在上面给出的示例中添加一个在Packet类中调用的自定义函数copy()。

class Packet;
...
 function copy (Packet p);
 this.addr = p.addr;
 this.data = p.data;
 this.hdr.id = p.hdr.id;
 endfunction
...
endclass
module tb;
Packet p1, p2;
initial begin
p1 = new (32'hface_cafe, 32'h1234_5678, 32'h1a);
p1.display ("p1");
p2 = new (1,2,3); // give some values
p2.copy (p1);
p2.display ("p2");
//Now let's change the addr and id in p1
p1.addr = 32'habcd_ef12;
p1.data = 32'h5a5a_5a5a;
p1.hdr.id = 32'h17;
p1.display ("p1");
// Now let's print p2 - you'll see the changes made to hdr id
// but not addr
p2.display ("p2");
end
endmodule

请注意,我们在 copy() 这里调用了自定义函数而不是浅拷贝方法,因此 Header 对象的内 容也应该被复制到p2中。请注意,即使p1的id字段已更改,对象p2的id仍保留先前的值。

1.3 copy(要点是需要先例化)

(1) copy对象不像想象的那么简单,简单的赋值语句obj2_h=obj1_h,并没有为obj2_h创建一个新的对象,而是指向了与obj1_h相同的对象;

(2) 为了真正的copy一个对象,需要先例化,然后copy data,如下图所示;

2.Shallow copy

2.1使用new操作符复制一个对象

(1)new操作符创建了一个新的对象,并且复制了现有对象的所有变量;但是如果类中包含一个指向另一个类的句柄,下层的对象都不会被复制;

注1:当调用new操作符进行复制的时候,Transaction对象被拷贝,但是Statistics对象没有被复制;

注2:当调用new操作符进行复制的时候,Transaction的new函数不会被调用;

3.Deep copy(需要调用类所包含的所有对象的copy函数)

posted @ 2023-01-29 20:01  luckylan  阅读(89)  评论(0编辑  收藏  举报