假设有父类句柄a,子类句柄b。
首先,进行a=b操作后,a和b都指向子类对象。若没有进行赋值操作,a指向父类对象。故当拿到一个父类句柄时,并不知道其当前指向的是父类对象还是子类对象。因此对编译器来讲,只允许父类句柄访问父类成员(即父类句柄只能访问子类对象里的父类成员),这样的内存访问方式是安全的。
从图中看,子类句柄赋值给父类句柄,相当于将访问范围从大三角区域限制为小三角区域。访问范围缩小,这是安全的。
其次,将父类句柄赋值给子类句柄,编译会直接报错。相当于将小三角区域扩大为大三角区域,这会造成内存泄露,编译器是不允许的。
SV中将父类句柄转化为子类句柄的唯一方法是$cast(b,a)。编译时遇到该函数会跳过,不会做类型检查,而后仿真过程中会动态地检查父类句柄是否指向子类对象,若是则允许类型转化,访问范围由小三角区域扩大为大三角区域。