SV学习笔记(九)-类

类的封装

  • 类是一种包含数据和方法(function、task)的类型
  • 例如一个数据包,可能被定义为一个类,类中可以包含指令、地址、队列ID、时间戳和数据等成员
  • packet这个类可以在其中对这些数据做初始化,设置指令,读取该类的状态以及检查队列ID
  • 每个packet类型化的具体对象及数据成员都不相同,然而packet类作为描述这些数据的抽象类型,将其对应的数据成员和操作这些数据成员的方法都定义在其中
  • OOP术语
    • 类(class):包含成员变量和成员方法
    • 对象(object):类实例化后的对象
    • 句柄(handle):指向对象的指针
    • 原型(prototype):程序的声明部分,包含程序名,返回类型和参数

构建函数

  • SV并不像C++一样要求复杂的存储空间开辟和销毁手段,二十采用了像java一样空间自动开辟和回收的手段

  • SV在类的定义时,只需要构建函数(constructor),而不需要定义析构函数(destructor)

  • 类在定义时,需要定义构建函数,如果未定义,则系统会自动帮助定义一个空的构建函数(没有形式参数,函数体亦为空)

  • 对象在创建时,需要先声明再例化,同时进行也可以

    // 定义一个类,类名:Packet
    class Packet;
        function new();	// 构造函数,没有返回值,也不需要void
        endfunction
    endclass
    
    Packet p = new();	// Packet:类,p:句柄,new():实例化出一个对象
    
    • 对象在运行之前,不会实例化,这时候对象p指向的是null
    • 对象在开始运行后,才会实例化,p才会指向一个句柄
  • 构建函数中传参数

    // 定义类
    class Packet;
        function new(int inival);
            command = inival;
        endfunction
    endclass
    
    initial begin
        // 例化
        Packet p = new(6);
        $display(p.command);
    end
    

静态成员(变量/方法)

  • 成员方法可以声明为静态

  • 静态方法无法访问非静态成员(方法/变量),否则会发生编译报错

  • 静态变量

    class Packet;
    		integer command;
    		static int my_data;
    		function new(int inival);
    			command = inival;
    		endfunction
    endclass
    initial begin
        Packet p1,p2;
        // 静态变量存储在类中,可以通过类直接获取
        $display("static data is %0d", Packet::my_data);
        // p1.my_data拿的是类中的值,这时还没有例化对象
        $display("static data is %0d", p1.my_data);
        $display("static data is %0d", p2.my_data);
    end
    
  • 静态方法

    class Packet;
        integer command;
        static int my_data;
        function static my_static_func();
            $display("this is static function");
        endfunction
        function new(int inival);	// 构造函数,没有返回值,也不需要void
            command = inival;
        endfunction
    endclass
    initial begin
    	Packet p1,p2;
        // 静态方法在类中,不例化对象也能调用
        p1.my_static_func();
        p2.my_static_func();
    end
    
    

this

  • this是用来明确索引当前所在对象的成员(变量/参数/方法)

  • this只可以用来在类的非静态成员、约束和覆盖组中使用

  • this的使用可以明确所指向变量的作用域

    class Packet;
        integer x;
        function new(integer x);
            this.x = x;	// this.x表示对象的x变量,而非传进来的x
        endfunction
    endclass
    
    

赋值和拷贝

  • 声明变量和创建对象是两个过程,也可以一步完成

    Packet p1;	// 声明变量
    p1 = new();	// 例化对象
    Packet p2 = new()	// 声明+例化
    
  • 如果就将p1赋值给另外一个变量p11,那么依然只有一个对象,只是指向这个对象的句柄有两个:p1、p11

    p11 = p1;	// 赋值
    
  • 以下这种方式表示p1和p12代表两个不同的对象,在创建p12时,将从p1拷贝其成员变量,这种拷贝方式称为浅拷贝(shallow copy)

    Packet p1;
    Packet p12;
    p1 = new();
    p2 = new p1;	// 注意,这里的new不能加()
    
  • 浅拷贝中,只拷贝了对象的值,如果对象某个变量变量另一个对象,那拷贝生成的对象那个变量也会指向相同的变量

在这里插入图片描述

  • 深拷贝(deep copy)指的是拷贝对象和对象变量指向的对象,所有都是新开辟空间存储,SV没有提供深拷贝,需要自己自定义

数据的隐藏和封装

  • 类的成员(变量/方法)默认情况下是公告属性的,这表示不管在类的内部和外部均可以访问该成员(变量/方法)
  • 对于商业开发,类的提供方会限制一些类成员的外部访问权限,继而隐藏成员的更对细节
  • 这种方式也使得类的外部访问接口更加精简,减轻了类的维护工作量,也使得类在修改时便于与旧版本保持兼容
  • 数据隐藏的方式是的类的测试和维护都变得更为简单
  • local:只有该类可以访问此成员,子类和外部均无法访问
  • protected:表示该类及其子类可以访问此成员,外部无法访问

类的继承

  • 通过extends,创建子类

    // 父类
    class ParentPacket;
        ...
    endclass
    
    // 子类
    class ChildPacked extends ParentPacket;
        ...
    endclass
    
  • 子类会默认调用父类的new()函数

  • 父类new()方法需要接收参数时,子类new()方法中不能再默认调用父类的new()方法,必需使用super.new()并传参对父类的方法进行调用

  • 子类和父类有相同的变量时,各自类的方法会修改各自类中的变量

  • 子类的对象可以赋值给父类的句柄

    class Packet;
        integer i = 1;
        function new();
            i = 2;
        endfunction
    endclass
    
    class ChildPacket extends Packet;
        integer i = 1;
        integer k = 5;
        function new();
            i = 3;
        endfunction
    endclass
    
    Packet tmp;
    ChildPacket p = new();
    
    tmp = p;	// 子类的对象可以赋值给父类的句柄
    $display("p.i is %0d", p.i) // 这里拿到的是子类中的i,例化之后i=3
    $display("tmp.i is %0d", tmp.i)	// 这里tmp虽然指向的是子类的对象,但是tmp是父类的句柄,因此tmp.i=2
    $display("tmp.k is %0d", tmp.k)	// 因为父类中不存在k这个变量,tmp.k就找不到,这段代码编译会报错
    
  • 父类的对象不能赋值给子类的句柄,编译会报错,因为可能会造成内存的非法访问

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值