SystemVerilog——学习笔记4(父类句柄和子类句柄的问题)


前言

2023.3.12 植树节


2023.3.15 更新
今天看到一个文章讲父类句柄和子类句柄的问题的

父类句柄可以指向子类对象(只可以访问部分内容)和父类对象
子类句柄只可以指向子类对象,不可以指向父类对象

父类句柄 = 子类句柄;  子类句柄可以直接赋值给父类句柄,不需要转换
$cast(子类句柄,父类句柄);  父类句柄给子类句柄需要转换,还有可能转换失败

结果:子类句柄指向父类句柄所指向的对象。此时若父类句柄指向的是子类类型的对象则结果就是子类句柄指向子类对象,仿真不会报错,但如果父类指向的是父类对象则结果就是子类句柄指向了父类对象,这是仿真不允许的,会报错。

转换的时候就是看父类句柄指向的对象类型是否是子类,是就输出1,转换成功,是父类对象的话,输出为0,转换失败


一、父类句柄h1、子类句柄h2

h1=h2:合法,但是在调用相同对象的成员时,有不同的表现。
赋值后父类还是只能调用父类的成员,子类可以使用super找到父类中的变量,但是父类不能够引用子类中的同名变量
在这里插入图片描述

举例说明

在这里插入图片描述
1、首先,创建了一个父类对象,然后让子类指针去指向父类对象,这是错误的。bad是空句柄,没有创建对象。父类句柄指向的父类对象,没办法转换;若父类指向的是子类对象,可以转换。如果使用cast强制转换的话,编译不会报错,但是转换会失败。
再者,子类bad指向了一个父类对象,bad_crc是在子类中的,所以也没办法调用。

Transaction tr;   //声明句柄
BadTr bad;
tr = new();   //创建父类对象
bad = tr; 
$display(bad.bad_crc);

2、下面是创建子类对象,让父类句柄指向子类对象,这样是可以的

bad = new();  //创建子类对象
tr = bad;  //父类句柄指向子类对象
if(!$cast(bad2,tr))  //动态类型转换,检查tr的源对象是否是bad2类型或者其子类
	$display("failed");
$display(bad2.bad_crc);
bad2.display();  //这里调用的是子类的函数

二、virtual虚函数

建议除了new()函数之外不能定义为虚方法,其余方法都定义为虚方法。添加了没有坏处(父类里面的所有成员变量和方法子类都会继承)

静态绑定:static binding,不同句柄调用的内容不一样
动态绑定:dynamic binding,利用虚方法virtual声明函数,称之为虚方法(并没有“虚变量”)。不需要担心句柄指向的对象类型是父类还是子类,它可以进行动态动态方法查找dynamic method lookup

  • 只需要在父类里面声明一次,尽量在最底层中继承
  • 虚方法的继承:方法task/function的继承必须遵循相同的参数和返回类型(完全相同),否则,子类定义的方法会归为同名不同参的其他方法
  • new不可以用virtual修饰,没有返回值,可以有参数
  • 如果没有定义为virtual的话,就会去调用父类的函数
  • 解决了父类句柄指向子类句柄中的同名方法的动态查找问题,解决不了父类句柄查找子类对象里面变量的问题,无论父类句柄指向的是父类/子类对象,都无法找到子类对象中的成员变量,唯一办法将父类句柄转换为子类句柄。(只有虚方法没有虚变量)
  • 如果函数同名,但参数类型或者个数不同,叫函数重载
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值