2012-07-24 113 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 - 沒有對象前綴,我希望它調用類之外的第二個函數。