1

以下のコードのオブジェクトは、一度だけインスタンス化されていますよね? したがって、インスタンス化された単一のオブジェクトには、値が 2 である単一の整数 i フィールドが含まれている必要があります。2 ではなく 1 が返されるのはなぜp.iですか? これは SystemVerilog に固有のものですか? それとも、すべての 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 

ありがとう

4

2 に答える 2

3

この例は、問題を説明している1800-2009SystemVerilog仕様のセクション8.13から貼り付けられています。私の意見では、このようにクラスのメンバーをオーバーライドすることは本当に悪い考えです。仕様の例は、それがどのように機能するかを説明するためのものです。

classプロパティinteger iは、基本クラスと子クラスの両方で定義されます。のこの宣言は、LinkedPacketの宣言を上書きして非表示にしますPacket

仕様から:

この場合、pへの参照は、Packetクラスのメソッドとクラスプロパティにアクセスします。したがって、たとえば、LinkedPacketのクラスプロパティとメソッドがオーバーライドされた場合、pを介して参照されるこれらのオーバーライドされたメンバーは、Packetクラスの元のメンバーを取得します。pから、LinkedPacketの新しいメンバーとすべてのオーバーライドされたメンバーが非表示になりました。

ハンドルを介して関数を呼び出しているのでPacket、から値を取得しますPacket

また、get()関数は宣言されていませんvirtual。これが、整数が否定されていない理由です。これは、仕様の例にも記載されています。

基本クラスオブジェクト(例ではp)を介してオーバーライドされたメソッドを呼び出すには、メソッドを仮想として宣言する必要があります(8.19を参照)。

この動作はSystemVerilogに固有のものではなく、他のオブジェクト指向言語で観察される動作と似ています。

iinに別の値を設定するLinkedPacket場合、これを行う適切な方法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
于 2012-07-24T14:36:02.163 に答える
0

私は SystemVerilog の専門家ではありませんが、それが初期化されたものである p.iため、戻ってくることを期待しています。は同じ値を返すもう 1 つの方法であるため、これも になります。1p.get()1

j=get();(私が思うに)戻り-2ます-オブジェクトプレフィックスがなければ、クラス外にある2番目の関数を呼び出すと思います。

于 2012-07-24T13:03:54.813 に答える