SystemVerilog-继承类的复制

文章探讨了在面向对象编程中,父类和子类之间的复制操作,包括父类句柄指向子类对象、子类句柄指向父类对象以及使用new函数的复制。强调了父类无法访问子类特有属性的限制,同时阐述了多态的概念,即通过子类赋值给父类后,调用virtual函数会执行子类的实现。
摘要由CSDN通过智能技术生成

子类与父类之间的复制

1. 父类的句柄指向子类的对象

对于子类来讲,通过复制操作,是可以直接赋值给父类,也就是说,父类的句柄可以直接指向子类。但是反过来操作,是不可以的,并且在指向的过程中,父类的句柄仍然无法访问子类的属性,父类和子类之间的赋值操作如下图所示代码块。

1.	program cls_cp;
2.	    class base_cls;
3.	        int a = 100;
4.	        inner_cls i_a;
5.	        function new();
6.	            i_a = new();
7.	        endfunction
8.	    endclass
9.	
10.	    class child_cls extends base_cls;
11.	        int b = 300;
12.	    endclass
13.	
14.	    initial begin
15.	        base_cls base_0;
16.	        child_cls child_0;
17.	        child_0 = new();
18.	        base_0 = child_0;
19.	    end
20.	
21.	endprogram

这种赋值操作,父类无需使用new函数,因为子类已经new过,分配好地址空间,赋值是将句柄赋值,因此父类的空间已经分配好,且父类和子类的对象是共享存储空间的。如下图所示:

仿一下看看:

       改变一个,另一个跟着改变。再试试改变父类的属性。

       可以注意到一个细节,虽然父类的句柄指向了子类,但是父类的句柄其实是指向了子类继承的父类所在内存空间,父类仍然是无法访问子类的属性的。

       直接报错,说在父类中找不到对象b,因此父类的句柄只是指向了子类的父类所划的空间。如果父类增加new操作呢?也是可以的,只是过程变为如下图所示:

2 子类的句柄指向父类的对象

       子类句柄赋值给父类的句柄操作,是可以的,那么反过来操作是否可以?答案是不行的,因为父类的句柄,并不包含子类的对象的属性,因此直接父类句柄直接赋值给子类的句柄,会造成访问错误,因为编译器认为,子类比父类包含更加丰富的信息,而父类的句柄类型决定了其不包含有子类的属性,这也是类的继承的特点,只有子类可以访问父类的成员变量,代码块如下:

1.	program cls_cp;
2.	    class base_cls;
3.	        int a = 100;
4.	        inner_cls i_a;
5.	        function new();
6.	            i_a = new();
7.	        endfunction
8.	    endclass
9.	
10.	    class child_cls extends base_cls;
11.	        int b = 300;
12.	    endclass
13.	
14.	    initial begin
15.	        base_cls base_0;
16.	        child_cls child_0;
17.	        base_0 = new();
18.	        child_0 = base_0;
19.	    end
20.	
21.	endprogram

仿一下看看:

可以看到直接报错了。

 3 使用new函数的复制

父类与子类之间的复制操作,同样可以通过new函数实现浅拷贝,值得注意的是,复制规则也只能由子类的句柄复制给父类,也就是父类的句柄只能指向子类的对象,反过来是不行的,实现规则同样为浅拷贝。代码如下:

1.	program cls_cp;
2.	    class base_cls;
3.	        int a = 100;
4.	        inner_cls i_a;
5.	        function new();
6.	            i_a = new();
7.	        endfunction
8.	    endclass
9.	
10.	    class child_cls extends base_cls;
11.	        int b = 300;
12.	    endclass
13.	
14.	    initial begin
15.	        base_cls base_0;
16.	        child_cls child_0;
17.	        child_0 = new();
18.	        base_0 = new child_0;
19.	    end
20.	
21.	endprogram

仿一下看看:

       这个实现的其实就是浅拷贝过程,如下图所示:

       浅拷贝内置类指向同一块地址空间。改变父类的顶层类,不会影响子类,但是改变深层类,会影响子类。

       反过来复制呢?会直接报错:

​​​​​

4 类的多态特性

       多态赋予了类更多的变化和可能性,类变量中用virtual修饰的函数或任务,在子类中可以进行改写,改写过后,通过子类赋值给父类的这种操作,父类再调用virtual修饰的函数时,其实是调用的子类的函数。仿一下:

       如果父类的函数没有被virtual修饰,子类没办法对父类的函数改写,因此也失去了多态的特性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值