SystemVerilog中这个this到底怎么回事
在面向对象语言中,this经常用来表示对当前对象的一个引用,可以理解为指向对象本身的一个指针,并且常作为类中方法的隐含形参,通过该形参可以访问对象内部的属性和方法,因此,一般方法对于编译器来说,原型结构如下:
[return_type] func_name(class_type const this,other_args)
其中
Ø return_type为方法返回类型
Ø class_type当前方法所属的类
Ø other_args当前方法其他形参
那么,this到底有什么作用如何使用呢?本文将通过示例,说明this在SystemVerilog类中如何使用。
上图中,当一个对象创建时,并没有为每个对象的方法单独创建空间存放,而是所有对象共用同一个成员方法,因为这些方法对于所有的对象都是一样的,只是传入其中的参数不同而已,方法完全可以通过this指向不同的对象实现对于不同对象不同属性值的访问,这种将方法作为共享的操作实现方式可以有效的减少对于磁盘空间的占用。通过这样的方式,当我们调用方法时,this将该方法与调用该方法的对象捆绑在一起,形参this会被初始化为调用该方法的对象的地址,从而可以实现对于调用方法的对象中的属性的访问。当然在方法中不必显式的使用this指针来访问该方法所属对象的属性和其他方法,此时对于这些没有采用this前缀进行访问的属性和方法都被假定为通过this实现了引用。
因为this在方法的形参表中是隐式定义的,不需要也不能在方法的形参表中包含this,否则会产生错误。但是this是可以作为方法的实参使用的,如下例所示。
【示例】
示例中,inline方法中通过this调用chg方法,并且将this作为实参传递给了chg(通过chg方法的定义可以看到this的类型为当前类)。在chg中,因为创建对象时并没有对sig2进行初始化,且sig2数据类型为logic,所以其默认值为x,打印出结果也为x。然后,在chg中通过pkt(传进chg的this)访问了sig1,sig1的值为当前对象创建时sig1初始化sig1的值’h5050,经过运算后赋给了隐含this指向的sig2(15行),即改变当前对象的sig2,并且分别通过隐含this引用sig2和pkt.sig2输出sig2的值,两个值相同,可见此时两者都指向同一sig2。这里我们需要注意,方法inline和chg都是普通方法,不是静态方法(静态方法是类的组成部分,不是对象的组成部分),在SystemVerilog中,静态方法中不能使用this,如下例所示。
【示例】
通过编译报错可以知道,在static中不能使用this指针。上述示例展示了如何通过this去访问对象的其他成员和一些注意事项,this除了上述示例描述的功能之外,还有另外一个用处,如下例所示。
【示例】
示例中,在packet的new函数的形参列表中,使用了跟packet属性相同的名字,在函数体中,通过“this.sig1 = sig1”将形参sig1赋值给了当前对象的“this.sig1”,此时使用this区分了表达式中的形参和对象的成员sig1,最后通过pkt.disp显示当前对象的sig1,此时sig1的值为对象创建时通过形参传入的数据,即’h5050。但是sig2在new函数中,并没有对表达式sig2进行区分,此时赋值表达式左右的sig2都为new函数的局部变量,即形参sig2,因此,此时并没有对对象的sig2进行赋值,所以通过pkt.disp显示的sig2不能获取到new形参中传入的sig2,此时对象的sig2的值就为“XXXX”。Sig3的情况与sig2类似,通过pkt.disp显示的为disp函数体的局部变量而不是对象成员,而pkt.disp_sig3显示的是当前对象的sig3.通过示例我们可以看到,如果形参中存在与类的属性相同的名字是,为了进行区分,在函数体中必须使用this区分形参和对象的属性,否则函数体中为当前函数体的局部变量(形参)。通过上述示例,this指针在SystemVerilog的特点和用处如下:
Ø 通过this可以绑定方法和对象;
Ø 通过this可以区分方法体的形参和对象的成员;
Ø this指针可以作为实参传递,但是不能作为形参使用;
Ø this指针在调用方法时开始存在,当方法调用结束时其生命周期也就结束了,这与一般函数的形参生命周期相同;
Ø this指针不能用于static方法中;