1.类型转换
- 类型转换包括隐式转换(如等号左右位宽不同)和显式转换,显式转换又可分为静态转换
'
(转换失败不会提示)和动态转换$cast(target,src)
- 父类句柄指向子类对象是可以的,但将一个父类句柄赋值给子类句柄在sv中是禁止的,需要通过
$cast()
实现句柄的动态转换,如果源对象和目的句柄是同一类型或者是目的句柄的扩展类则会转换成功。
2.虚方法
※由于类的多态性,通过虚方法就可以实现动态绑定,不需要担心句柄指向的对象类型是父类还是子类。
- 非虚函数的调用。子类句柄赋值给父类,造成无法用父类句柄直接找到子类方法。并且值得注意的是子类覆盖的方法并不会继承父类同名的方法,只用通过
super.method()
方式显式执行,才会达到继承父类方法的效果。 - 虚函数的调用。动态绑定——在运行时来确定句柄指向对象的类型,再动态指向应该调用的方法。通过虚方法的使用来实现类成员方法调用时的动态查找。
- 虚方法
virtual
尽量定义在底层父类,只需声明一次。虚方法的继承需要遵循相同的参数和返回类型。
3.对象拷贝
- 对象的拷贝无法通过
=
实现,这一操作实现的只是句柄的赋值而不是对象的拷贝。
class basic_test;
...
virtual function void copy_data(basic_test t);
t.def = def;
t.fin = fin;
endfunction
virtual function basic_test copy();
basic_test t = new(0);
copy_data(t);
return t;
endfunction
endclass
class test_wr extends basic_test;
...
function void copy_data(basic_test t);
test_wr h;
super.copy_data(t);
$cast(h, t); //注意句柄类型转换,确保转换后的句柄可以访问类成员变量
h.def = def;
endfunction
function basic_test copy();
test_wr t = new();
copy_data(t);
return t;
endfunction
endclass
4.回调函数
理想的验证环境是在被移植时尽可能的做水平复用或者垂直复用。通过在父类定义方法时,预留回调函数入口,使得在继承的子类中填充回调函数就可以完成对父类方法的修改。
5.参数化的类
class xxx #(type T=int);
local T queue[$];
...
endclass