4.3-类:继承的规则(含local/protected概念),对象空间分配,虚方法和多态

资料来源:

(1) system verilog与功能验证-钟文枫(注:关于虚方法和多态的讲解,该本资料最佳);

(2) 硅芯思见:【107】SystemVerilog中的多态和虚方法 (qq.com)

(3) Verilog系列:【62】local和protected保护类成员 (qq.com)

(4) Verilog系列:【58】SystemVerilog中基类和派生类之间的赋值 (qq.com)

(5) Verilog系列:【61】virtual在类中的使用 (qq.com)

1.继承的一些基本规则

(1) 子类继承父类的所有数据成员(local除外)和方法;
(2) 子类可以添加新的数据成员和方法;
(3) 子类可以重写基类中的数据成员和方法(overwrite & override);
篇5-类中的overwrite与override - 蚕食鲸吞 - 博客园 (cnblogs.com)
(4) 子类可以通过super操作符引用父类中的方法和成员;
(5) 被声明为local的数据成员或方法只能对自身可见,而对于外部和子类不可见(子类不能继承得到);

(6) 被声明为protected的数据成员或方法对外部不可见,对于自身和子类可见.

注:类中的属性和方法的访问属性默认为public,其中的任何成员都可以通过该类的对象被访问;

2.对象空间分配

(1) 类的对象被定义的时候,只是一个空的句柄;当其构造函数被调用的时候,才分配空间,其句柄指向该片空间的入口地址;

(2) 派生类的对象被定义的时候,也只是一个空句柄,当构造函数被调用的时候,分配的空间不仅有来自父类的继承而来的数据和方法,还有自己添加的部分;其中,新添加的数据成员和方法存储在独立的空间中,保持与继承成员和方法的独立性;

 

       

3.虚方法与多态

3.1 背景
3.1.1基类

class Packet;

  task build_payld();

    $display("Packet payld");

  endtask

 

  task build_packet();

    ......

    build_payld();

    ......

  endtask

3.1.2派生类

class DerivedPacket extends Packet;

  task build_payld();

    $display("DerivedPacket payld");

  endtask

endclass

3.1.3测试代码

module poly1;

  DerivedPacket der=new();

  initial der.build_packet();

endmodule

3.1.4测试结果

Packet payld

3.1.5测试结果分析

(1) 派生类对象在调用其build_packet过程中,会调用build_payld这个任务;而build_payld这个任务在父类扩展的过程中被重写过;虽然这样,最终调用的build_payld仍是父类中的build_payld,而不是子类中的build_payld.因为默认情况下,子类中重写的方法对于父类是不可见的(父类句柄不能访问子类重写的方法,除非父类中也存在同名方法,且该方法为虚函数).

(2) 派生类对象的空间分配分为两个部分,一部分来自父类的继承部分,一部分是重写或新增的部分.默认情况下,父类的方法是无法访问派生类的重写和新增部分的。假如希望重写的方法被父类看到,就需要依靠虚方法和多态.

3.2虚方法与多态
(1) 类中的方法可以在定义的时候通过添加virtual关键字来声明一个虚方法,虚方法是一个基本的多态性结构.

(2) 虚方法为具体的实现提供一个原型,也就是在派生类中,重写该方法的时候必须采用一致的参数和返回值,但是子类中重写的方法可以不用添加virtual关键字.

注:一个方法在被重写的时候可以声明为虚方法,一旦方法被声明为虚方法,它在后续的继承过程中就永远是一个虚方法,不管重写的时候是否使用virtual;

(3) 虚方法可以重写其所有基类中的方法,然而普通的方法被重写后只能在本身及其派生类中有效。

(4) 每个类的继承关系只有一个虚方法的实现,而且是在最后一个派生类中。

 

(5) 在P1指向P2后,当P1.printA被调用的时候,程序会调用访问内存中类对象P2中P1的部分,而此时发现printA是一个普通方法,为此直接调用并结束访问;

(6) 在P1指向P2后,当P1.printB被调用的时候,程序同样找到类对象P2中P1的部分,此时发现printB是个虚方法,这时其会咨询系统,查看整个P2在定义的时候是否重写了该方法.系统发现在P2中(除了P1外),确实重写了该方法,为此,程序会直接调用P2重写的实现.

(7) 带有虚方法的类称为多态类.虚方法与重写的实现就是多态!当父类的对象指向不同的子类时,虚方法就表现出了不同的实现方法,呈现多态;

注:实现多态需要三个步骤:1)在父类中定义虚方法; 2)在子类中重写父类中的虚方法; 3)声明父类句柄,该句柄可以指向父类对象,也可以指向子类对象;当指向父类对象时,调用的是父类方法;当指向子类对象时,调用的是子类同名方法;

posted on 2021-11-18 16:40  知北游。。  阅读(221)  评论(0编辑  收藏  举报

导航