Что произойдет, если мы назначим дочерний дескриптор родительскому дескриптору и результат в случае доступа к родительскому дескриптору?

#system-verilog

Вопрос:

Постановка задачи: существует 2 класса (родительский и дочерний классы). Оба display они выполняют в нем одну и ту же функцию. Я назначил дескриптор дочернего класса дескриптору родительского класса с помощью « p=c; » после этого я пытался получить доступ p.display() , но , в моем понимании, он должен использовать функцию из дочернего класса. Но после запуска я вижу, что он печатается из родительского класса. Есть какие-нибудь догадки, почему?

 class parent;
  function void display();
    $display("I am in parent");
  endfunction
endclass

class child extends parent;
  function void display();
    $display("I am in child");
  endfunction
endclass

module tb;
  parent p;
  child c;

  initial begin
    p = new();
    c = new();
    $display("1: %d    %d", p , c);
    p = c ;
    $display("%d    %d", p , c);
    p.display();

  end

endmodule
 

Ответ №1:

Ваш пример почти идентичен примеру в IEEE Std 1800-2017, раздел 8.14 Переопределенные члены. Поведение вашей симуляции подробно описано там:

Чтобы вызвать переопределенный метод с помощью объекта базового класса (p в примере), метод должен быть объявлен виртуальным.

Чтобы добраться p.display до I am in child этого , вы должны объявить свои display функции как virtual :

 class parent;
  virtual function void display();
    $display("I am in parent");
  endfunction
endclass

class child extends parent;
  virtual function void display();
    $display("I am in child");
  endfunction
endclass
 

Ответ №2:

Родитель и ребенок-плохой выбор для описания наследования классов. При создании расширенного класса существует только один объект, содержащий свойства базового и расширенного классов.

Когда вы используете переменную базового класса для доступа к свойствам в объекте расширенного класса, вы можете получить доступ только к свойствам, известным типу переменной базового класса.

Поэтому, когда вы используете p переменную класса, она вызовет parent::display (), даже если child::display существует, но он скрыт.

Если вы объявите parent::display как виртуальный метод, только тогда он будет искать наиболее расширенное переопределение этого метода.