2012-07-24 94 views
1

下面代码中的对象已经实例化一次,对吧?所以实例化的单个对象应该包含一个值为2的整数i字段。为什么p.i给出1而不是2?这是特定于SystemVerilog吗?或者所有的操作语言都有相似的表现?系统verilog/oop

class Packet; 
    integer i = 1; 
    function integer get(); 
    get = i; 
    endfunction 
endclass 

class LinkedPacket extends Packet; 
    integer i = 2; 
    function integer get(); 
    get = -i; 
    endfunction 
endclass 

LinkedPacket lp = new; 
Packet p = lp; 
j = p.i; // j = 1, not 2 
j = p.get(); // j = 1, not -1 or –2 

感谢

+0

在第一行多行类/函数定义的末尾添加分号似乎会让人感到困惑,因为分号在其他地方用于指示语句结束。 SystemVerilog是否需要? – JAB 2012-07-24 19:32:17

回答

3

本例来自1800-2009 SystemVerilog规范的第8.13节,它解释了这个问题。我的意见是,这样的压倒一切的班级成员是一个非常糟糕的主意。规范中的例子就是为了说明它的工作原理。

类属性integer i在基类和子类中都有定义。 LinkedPacket中的此声明覆盖并隐藏了Packet中的声明。

从规范:

在这种情况下,至p的访问的方法和分组类的类属性的引用。因此,例如,如果 LinkedPacket中的类属性和方法被覆盖,则这些被覆盖的成员通过p指向 ,从而获得Packet类中的原始成员。从p, LinkedPacket中新的和全部重写的成员现在都隐藏起来了。

因为你是通过调用句柄Packet功能从Packet得到的值。

另外,get()函数未被声明为virtual。这就是为什么你看不到整数被否定的原因。这在规范的例子中也有说明。

要通过基类对象(示例中的p)调用重写的方法,该方法需要声明为 virtual(请参见8.19)。

此行为对于SystemVerilog不是唯一的,与您在其他OO语言中观察到的情况类似。

如果要在LinkedPacket中为i设置不同的值,则正确的方法是仅在基类中声明i,并在构造函数中以不同的方式初始化它。

例如

class Packet; 

    integer i; 

    function new(); 
    i = 1; 
    endfunction 

    virtual function integer get(); 
    get = i; 
    endfunction 

endclass 

class LinkedPacket extends Packet; 

    function new(); 
    i = 2; 
    endfunction 

    virtual function integer get(); 
    get = -i; 
    endfunction 

endclass 
+0

感谢您的时间和精力,Dwikle。我来自java背景,并花了我一些时间才明白在系统verilog中使用虚拟来实现多态。 :) – claudius 2012-08-03 05:15:44

+0

@ user1023638 - 很高兴帮助。如果问题解决了,请记住接受答案。 – dwikle 2012-08-03 14:55:00

0

我不是SystemVerilog的专家,但是我希望p.i返回1因为这是你把它初始化到。 p.get()只是另一种返回相同值的方式,所以也会是1

j=get();将(我认为)返回-2 - 没有对象前缀,我希望它调用类之外的第二个函数。