class Transaciton;
static count = 0;
int id;
statics status;
function new();
status = new();
id = count ++ ;
endfunction
endclass
Transaction src,dst;
initial begin
src = new();
dst = new src; // 使用new函数复制
src.status.name = 11; // 改变第二层类中的值
dst.status.name = 22; // 改变目标对象中第二层对象的值
$display("%d",src.status.name); //打印的值是22
end
SystemVerilog中可以使用new函数复制一个对象到新的对象,但是这种复制只会复制对象现有的变量,所有自己定义的new函数都不会被复制。也就是说,如果一个类中使用了另一个类的句柄,并且实例化了这个类的对象,使用new函数复制顶层的类的对象时,第二层的对象的句柄会被复制进去。也就是说,如果实例化了两个顶层对象,对其中一个对象里面的对象的属性进行修改时,同样会修改另一个顶层对象中的属性,因为第二个对象复制第一个对象的时候会将句柄也复制过去,而不会使用自己定义的new函数重新实例化对象,因此在第二个对象中修改属性时,实际上是通过第一个对象中句柄的地址访问对象的属性,因此,虽然只修改了一个属性,但是在两个顶层对象中引用的时候,属性的值都被改变了。上面的代码中就存在这种问题。因此为了防止对象的属性被意外地修改,可以使用copy函数。
function Transaction copy;
copy = new(); // 创建新的变量;
copy.id = id;
copy.status = status.copy(); // statics类也要有自己的copy函数
id = count ++ ; // 每次使用new都要让count 自增一次
endfunction
创建类的时候最好创建copy函数,让其它类实例化该类的时候,copy不需要再去修改原有类。