systemverilog:virtual 关键字的用法

我在csdn上查询了systemverilog中关于virtual关键字的用法,发现了好多人都说了这么一句话:

virtual function/task:
用于OOP思想的继承使用。当定义了virtual时,在子类中调用某function/task,会先查找在子类中是否定义该function/task,如果没有定义该function/task,则在父类中查找。未定义virtual时,只在子类中查找,没有定义就是编译错误。

我觉得这句话说得太迷惑人了,会让初学者理解上出现偏差。
而且这句话:
未定义virtual时,只在子类中查找,没有定义就是编译错误
是完全错误的!

class前加不加virutal的区别很容易理解,下面我重点解释一下function前面加virtual和不加virtual的区别。(以下的代码没编译过,大家领会精神即可)。

场景1

在这里插入图片描述

class A 的call_disp() 和disp()声明时加入了virtual,class B没有直接声明call_disp(); 当第37行(子类B调用A的call_disp函数)开始执行时,打印的内容是:
I am B

场景2:

在这里插入图片描述

Class A 的call_disp() 声明时没有virtual, 同时disp()也没有加virtual; class B没有直接声明call_disp(); 当第37行开始执行时,打印的内容是:
I am A

场景3:

在这里插入图片描述

Class A 的call_disp() 声明时没有virtual, 但是disp()加了virtual; class B没有直接声明call_disp(); 当top第37行开始执行时,打印的内容是:
I am B

场景4:

在这里插入图片描述

Class A 的call_disp() 声明了virtual, 但是disp()没有加virtual; class B没有直接声明call_disp(); 当第37行只开始执行时,打印的内容是:
I am A

场景5

此场景是为了反驳:
未定义virtual时,只在子类中查找,没有定义就是编译错误
这一错误。
在这里插入图片描述
Class A 的call_disp() 和disp()没有加virtual; class B直接声明call_disp(),但没声明disp(); 当第37行只开始执行时,打印的内容是依旧是:
I am A

看到没有,根本没有什么编译错误。

场景6

在这里插入图片描述
Class A 的call_disp() 和disp()没有加virtual; class B直接声明call_disp()和disp(),但是call_disp()没有重写代码,而是使用super关键字直接继承父类中的call_disp();
当第37行只开始执行时,打印的内容还是:
I am A

惊不惊喜,意不意外!!!

总结

对于父类A,其中有两个函数: FunX和 FunY, 同时FunY调用了FunX;
子类B继承自A,如果B没有直接声明FunY,同时父类A中FunY又没有加入virtual, 同时B又修改了FunX

那么,当B实例化后,调用FunY函数后,FunY调用的是没有修改过的FunX!B类的FunX算是白修改了

为了 避免这种情况,你只能在B类中,也把FunY也重新写一遍(不能用super关键字)。

所以,父类的function在声明时,最好都加上virtual,这样子类就可以不用直接声明父类中出现的函数,这样比较节省代码(这是好处之一)。

  • 11
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值