SV-- cast类型转换练习(8/26)

        在SV中,cast作为一个显示的转换方法,一个重要的应用就是在类继承过程中实现类型的向下转换;

        向上转换:将扩展类句柄(child_handle) 赋给 父类(father_handle)

        father_handle = child_handle

        向下转换 :将父类句柄(father_handle) 赋给 扩展类(child_handle)
        child_handle = father_handle

        在SV中,编译允许基类句柄指向子类对象,这是合法的;但是不允许子类句柄指向基类对象,这样可能会造成数据的丢失,是不合法的,在SV编译时会检查句柄类型,会报错。

        类型向下转换需要使用cast,cast是检查对象类型,而不是检查句柄类型。

实验代码:

class father;
	string m_name;
	
	function new(string name);
	m_name = name;
	endfunction
	
	function void print();
		$display("HELLOW %s",m_name);
	endfunction
endclass:father

class child0 extends father;
	string car="car";
	
	function new(string name);
	super.new(name);
	endfunction
endclass:child0

class child1 extends father;
	string plane="plane";
	
	function new(string name);
	super.new(name);
	endfunction
endclass:child1

module top;
	father f;
	child0 c0;
	child1 c1;
	child1 c2;
	initial begin
		f=new("father");
		f.print();
		c0=new("child0");
		f=c0;
		f.print();
		c1=new("child1");
		f=c1;
		f.print();
		c1.plane="big_plane";
		$cast(c2,f);
		f.print();
		$write(",has %s", c2.plane);
		end
endmodule:top

 仿真结果:

 代码解析:

f=new("father");//为父类开辟空间,此时m_name为father

f.print(); //调用函数print 打印Hellow father

c0=new("child0");//为child0子类开辟空间,此时car=car,m_name=child0;

f=c0;//父类句柄指向子类child0对象,父类car=car,m_name=child0;

f.print();//调用函数print打印Hellow child0

c1=new("child1");//为child0子类开辟空间,此时plane=plane,m_name=child1;

f=c1; /父类句柄指向子类child0对象,父类plane=plane,m_name=child1;

f.print();//调用函数print打印Hellow child1        

c1.plane="big_plane";//显式将c1.plane赋值为big_plane,此时父类f.plane也赋值为big_plane

$cast(c2,f);//将c2悬空的句柄指向c1,c2.plane=big_plane,m_name=child1

f.print();//调用函数print打印Hellow child1

$write(",has %s", c2.plane);//打印,has big_plane

打印结果: 

上边的练习做完了,但是cast的魅力你真的有感受到吗?可能还真没有,那就让我们通过下边的代码再细细感受一下cast到底做了什么,她的魅力究竟在何处!

 首先进行一个简单的代码修改:

class father;
	string m_name;
	
	function new(string name);
	m_name = name;
	endfunction
	
	function void print();
		$display("HELLOW %s",m_name);
	endfunction
endclass:father

class child0 extends father;
	string car="car";
	
	function new(string name);
	super.new(name);
	endfunction
endclass:child0

class child1 extends father;
	string plane="plane";
	
	function new(string name);
	super.new(name);
	endfunction
endclass:child1

module top;
	father f;
	child0 c0;
	child1 c1;
	child1 c2;
	initial begin
		f=new("father");
		f.print();
		c0=new("child0");
		f=c0;
		f.print();
		c1=new("child1");
		f=c1;
		f.print();
        $display("f.plane=%s",f.plane);
		//c1.plane="big_plane";
		//$cast(c2,f);
		//f.print();
		//$write(",has %s", c2.plane);
		end
endmodule:top

修改内容:

去掉cast代码,加入一行代码: $display("f.plane=%s",f.plane);

要求打印出 f.plane;

编译结果会报错:

 这是因为在SV编译时会检查句柄类型,而不是对象类型,会报错。所以就出现了练习的代码,使用cast进行对象转换,再对子类变量进行访问;

可能有的小伙伴还是很迷茫,为什么要进行两部操作,直接通过c1去访问不就好了,有什么应用场景呢?由于博主实际项目经验较浅,这部分内容待后续补上,感兴趣的小伙伴可以自己去搜一下,或者已经了解的小伙伴,也可以分享出来哦,大家一起进步!

 

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

创芯人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值