SystemVerilog----类中面向对象编程OOP的基础概念

目录

一、面向对象编程(OOP)概述

二、OOP术语

三、创建新对象

四、静态成员(变量/方法)

五、this指针

六、在类中声明另一个类句柄

七、对象句柄的赋值与拷贝、数据的隐藏和封装 


一、面向对象编程(OOP)概述

OOP(Object Oriendted Programming),即面向对象编程。OOP使用户能够创建复杂的数据类型,并且将它们跟使用这些数据类型的程序紧密结合在一起。

在SV中,类可以定义在program、module、packge中,或者这些块之外的任何地方,并且类可以在模块和程序中使用。当项目中,单独类文件太多时,可以使用包(package)将一组相关的类和类型定义捆绑在一起。

面向对象编程OOP即将一切事物和具体问题进行抽象概括,并将其看作是一类对象。数据抽象就是对现实世界的一种抽象,而类(class)是一种用来进行数据抽象的工具,体现的是面向对象程序设计中的抽象特性。类不仅体现抽象的特性,还体现面向对象程序设计中封装的特点。

类的封装,就是将抽象得到的数据和行为相结合,形成一个有机的整体。即,将数据(变量)与数据操作的函数(方法)代码进行有机整合,形成类class,其中数据和函数都是类的成员。类class可以看作是一种特殊的结构体,类中不仅有数据,还可以有函数或任务,即包含成员的变量和方法。

类和结构体的联系和差别有哪些?

联系:类和结构体都可以封装成员变量

差别:类还可以封装成员方法,类需要使用new()来创建对象

通常,类中对于一个问题的描述应该包括两个方面:静态特性的变量抽象(用数据描述)和动态特性的方法抽象(用函数或任务描述)。

二、OOP术语

(1)  类(class):包含成员变量和方法(子程序)的基本构建块,类似于Verilog中的模块(module),将数据和对数据的操作封装在一起。

(2) 对象(object):类的实例化,即类例化后的实例(实体)。

(3) 句柄 (handle):指向对象的指针,就像一个对象的地址。

(4) 原型 (prototype):程序的(头)声明部分,包含程序名,返回类型和参数列表。程序体则是包含了执行代码。

(5)方法 (method):操作变量的程序代码,如任务task和函数function

(6)属性(property):类中存储数据的变量,类似verilog中的reg和wire类型的信号。

一个很好的比喻,将看作一个房子的设计蓝图(blueprint),描述了房子的结构,图纸不能住人,需要建造一座实际的房子,一个对象就是一个实际的房子,根据设计图可以建造房子的各个部分,像类也可以创建很多的对象,房子的地址就像一个句柄,它唯一标志了你的房子。房子里的带有开关的灯(开或者关),像是类中的变量用来保存数值,子程序用来控制这些数值。

三、创建新对象

类在定义时,需要定义构建函数new(),如果未定义系统会自动帮助定义一个空的构建函数(没有形式参数,函数体亦为空),类本身并不占用内存空间,而对象实例会占用内存空间。

  • 如果一个对象没有句柄指向时,其内存空间将被释放;
  • 可通过将句柄设置为null,手动释放内存空间;

对象在创建时,需要先声明再例化,同时进行亦可。

一般用类需要三个步骤 :

定义class——声明一个handle——new()函数开辟空间创建对象

class Packet;         // 1.自定义创建类class
  integer command;    //属性——数据变量
  function new () ;   //方法——函数,或称对数据的操作
    command =IDL.E;
  endfunction
endclass
Packet p; //2.句柄声明
p = new ; //3. 创建对象,分配内存空间

initial begin
 
  $display("*****handle p is :%h",p);        //打印基地址

end

声明句柄p时,它被初始化为null.然后用new()函数为Packet创建对象并初始化变量为默认值(二值为0,四值为X),并返回保存对象的地址。

new()与new[]异同

1.都申请内存并初始化变量

2.new( )用于创建一个对象,可以使用参数设置对象的数值

3.new[ ]用于建立一个含有多个元素的数组,只需要使用一个数值来设置数组的大小

四、静态成员(变量/方法)

·类的成员(变量/方法)默认都是动态(automatic)生命周期,·如果多个对象为了共享一个成员(变量/方法),那么可以为其添加关键字static

·同一个类多个对象因此可以共享同一个成员变量或者方法。

class Packet ;
  static integer fileID = $fopen ( "data" , "r”);
  ...
endclass

Packet p;

c = $fgetc( p.fileID ) ; // OR Packet: : fileID



class id;

  static int current = 0 ; //static声明——静态数据成员(静态变量)
  static function int next_id() ; //定义静态函数成员
    next_id = ++current; // oK to access static variable 静态函数调用静态变量
  endfunction

endclass


transaction::current;           //不通过句柄实现静态变量的调用
  • 静态数据成员用于存储可变数据,可用于记录一个类所创建的实例对象的数量;
  • 静态(函数)方法无法访问非静态成员(变量/方法),只能处理静态数据成员,否则会发生编译错误。且可以不通过句柄实现静态函数成员的调用(用域操作符 ::);

五、this指针

  •  this是用来明确索引当前所在对象的成员(变量/参数/方法)。
  •  this只可以用来在类的非静态成员、约束和覆盖组中使用。
  • this的使用可以明确所指向变量的作用域。
class Demo ;
  integer x;
   function new (integer x) ;
    this.x = x ;
   endfunction
endclass

六、在类中声明另一个类句柄

常见的类的成员包括四个主要部分:

  1. 数据变量;
  2. 对数据的操作(方法与任务);
  3. 其它类的句柄;
  4. 约束语句块;

  在对外部的类创建对象时,内部声明的类也会同时创建对象,默认含有内部类的new函数;在创建外部类对象时,会对类中的成员赋值,在这个过程中,内部另一个类的句柄也会同时被赋值,从而有了一个具体的基地址,即创建了内部类的对象。


七、对象句柄的赋值与拷贝、数据的隐藏和封装 

Packet p1 ;
Packet p2 ;
p1 = new ;
p2 = new p1 ; //浅拷贝
p2.copy(p1);              //深拷贝,自定义copy函数

·如果将p1赋值给另外一个变量p2,那么依然只有一个对象,只是指向这个对象的句柄有p1和p2.
·以下这种方式表示p1和p2代表两个不同的对象。在创建p2对象时,将从p1拷贝其成员变量例如integer、string和句柄等,该种拷贝方式称为浅拷贝(shallow copy) 。

1)、 浅拷贝只拷贝对象中的数据变量,浅拷贝前后的数据变量使用不同的内存空间;而对于对象中的数据操作(任务和函数)和其中定义的其它类的句柄,采取类似“引用操作”的方式,浅拷贝前后共用同一内存空间(浅拷贝不会复制嵌套的对象,只是复制了句柄)。

2)、 深拷贝:对于对象中的所有成员统一分配新的内存空间,区别于浅拷贝。

数据的隐藏和封装 

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


参考链接:https://blog.csdn.net/weixin_46022434/article/details/105431180

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值