SV,class学习笔记三,虚方法(virtual method)、多态(polymorphic)

1.当基类中没有使用虚方法

class Basic; //定义基类
	int addr;

	function new(int addr);
		this.addr = addr;
	endfunction

	function display();
		$display("\n[basic] addr = %0d\n",addr);
	endfunction
	
endclass

class Sub extends Basic; //定义扩展类

	int data ;
	
	function new(int addr,data);	
		super.new(addr);
		this.data = data;
	endfunction

	function display();
		$display("\n[sub] addr = %0d, data = %0d\n",addr,data);
	endfunction
	
endclass 

module tb;

	Basic b_handle;
	Sub   s_handle;

	initial begin
		s_handle = new(10,11); //new一个扩展对象
		b_handle = s_handle; // 使基类句柄指向扩展对象
		b_handle.display;  //指向扩展对象的基类句柄,调用基类中的方法,而不是扩展类中的方法	
	end
endmodule

        未使用virtual关键字时。指向扩展对象的基类句柄,调用基类中的方法,而不是扩展类中的方法,此时调用的是Basic::display。

 2.当基类中使用虚方法(virtual)时

class Basic;
	int addr;

	function new(int addr);
		this.addr = addr;
	endfunction

	virtual function display(); //基类中使用虚方法
		$display("\n[basic] addr = %0d\n",addr);
	endfunction
	
endclass

class Sub extends Basic;

	int data ;
	
	function new(int addr,data);	
		super.new(addr);
		this.data = data;
	endfunction

	function display();
		$display("\n[sub] addr = %0d, data = %0d\n",addr,data);
	endfunction

	
endclass 

module tb;

	Basic b_handle;
	Sub   s_handle;

	initial begin
		s_handle = new(10,11);
		b_handle = s_handle;
		b_handle.display;	
	end
endmodule

         当决定调用虚方法时,sv会根据对象的类型而非句柄的类型来决定调用什么方法,这里调用的就是 Sub::display。

3.直接将基类的句柄赋值给扩展类句柄是非法的

module tb;

	Basic b_handle;
	Sub   s_handle;

	initial begin
		b_handle = new(10);
		s_handle = b_handle;//将基类句柄赋值给扩展类句柄
		s_handle.display;	
	end
endmodule

 4.使用$cast将基类句柄赋值给扩展类句柄

4.1 当$cast里句柄所指向的对象不是同一类型,编译报错,赋值不用成功。

module tb;

	Basic b_handle;
	Sub   s_handle;

	initial begin
		b_handle = new(12); 

        //b_handle指向基类对象,s_handle是扩展类的句柄,二者不兼容
		$cast(s_handle,b_handle);

		s_handle.display;	
	end
endmodule

 

 4.2 $cast会检查句柄所指向的对象,只有源对象和目的对象是同一类型,才能赋值成功。

class Basic;
	int addr;

	function new(int addr);
		this.addr = addr;
	endfunction

	function display();
		$display("\n[basic] addr = %0d\n",addr);
	endfunction
	
endclass

class Sub extends Basic;

	int data ;
	
	function new(int addr,data);	
		super.new(addr);
		this.data = data;
	endfunction

	function display();
		$display("\n[sub] addr = %0d, data = %0d\n",addr,data);
	endfunction

	
endclass 

module tb;

	Basic b_handle;
	Sub   s_handle,s_handle1; //定义两个不同的扩展类句柄

	initial begin
		b_handle = new(12);    //基类句柄new一个对象
		s_handle = new(10,11); //扩展类句柄new一个对象
		b_handle = s_handle;   //扩展类句柄赋值给基类句柄,基类句柄指向扩展类对象
		$cast(s_handle1,b_handle);//从基类句柄中拷贝扩展对象的地址给另一个扩展类句柄
		s_handle1.display;     //扩展类句柄指向扩展对象调用Sub::display
		b_handle.display;	   //基类句柄调用 Basic::display
	end
endmodule

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值