Accessing Overridden and non-overridden members of a class with base class handle

Hi @dave_59

While going through SystemVerilog LRM, Chapter 8.14 Overridden Members, it is mentioned that when Base class members (i.e. properties and methods) are overridden (i.e. defined again with the same name) in an extended class and when assignment Base = Extended is done, then references to Base access the properties and methods of the Base class instead Extended class (Example 1: Overridden members).
And members are not overridden, then references to Base access the properties and methods of the Extended class (Example 2: Non-overridden and overridden members).

So, I have created two examples below and need clarification on the 2nd example.

Example 1: Overridden Members

In this example, I have overridden both property and methods in an extended class. Then trying to access property and methods using Base handle after Base = Extended.

module top;
  class Base;
     integer i = 1;
    
     function integer get();
       get = i;
     endfunction

     function void display();
       $display("Base: I: %0d", i);
     endfunction
  endclass

  class Extended extends Base;
    integer i = 2;

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

    function void display();
      $display("Extended: I: %0d", i);
    endfunction
  endclass

  initial begin
    Base b;  Extended e;
    b = new();  e = new();
    $write("Before assigning Extended to Base\n");
    b.display();    // Call Base::display()
    e.display();    // Call Extended::display()
    $write("After assigning Extended to Base\n");
    b = e;
    b.display();   // Call Base::display() - because of non-virtual method
    e.display();   // Call Extended::display()
    j = b.i;           // Access Base::i - As per LRM 8.14
    $display("Value of J: %0d", j);
    j = b.get(); 
    $display("Value of J: %0d", j);
  end
 endmodule

Output: Example 1: Overridden members

Output is as expected

# Before assigning Extended to Base
# Base: I: 1
# Extended: I: 2
# After assigning Extended to Base
# Base: I: 1
# Extended: I: 2
# Value of J: 1
# Value of J: 1

Example 2: Non-overriden and overriden members

In this example, only method has overridden in an extended class.

module top;
  class Base;
    integer i = 1;
    
    function void display();
      $display("Base: I: %0d", i);
    endfunction
  endclass
  
  class Extended extends Base;

    function void display();
      $display("Extended: I: %0d", i);
    endfunction
  endclass
  
  initial begin
    integer j;
    Base b;
    Extended e;
    b = new();
    e = new();
    $write("Before assigning Extended to Base\n");
    b.display();    // Access Base::display() - I = 1 (as expected)
    e.display();    // Access Extended::display() - I = 1 (as expected)
    b = e;
    e.i = 2;
    $write("After assigning Extended to Base\n");
    b.display();    // Access Base::display() - So, should print I = 1, but I = 2 is printed (not as expected)
    e.display();	   // Access Extended::display() - I = 2 (as expected)
    j = b.i;		   // Access Extended::i  (as expected)
    $display("Value of J: b.i: %0d",j);  // J = 2 (as expected)
  end
endmodule

Output: Example 2: Non-overridden and overridden members

Output is not expected when b.display() is called after b = e;

# Before assigning Extended to Base
# Base: I: 1
# Extended: I: 1
# After assigning Extended to Base
# Base: I: 2
# Extended: I: 2
# Value of J: b.i: 2

So, my query is why the value of I is printed as 2 when called b.display(); after b = e; statement ? I am expecting the value of I as 1 because of the following reasons:
First: The display() method is overridden in an extended class, so references to b access the methods result in accessing Base class method and should print 1.
Second: The display() method is non-virtual, so Base class method should be called and shoud print 1.

Thanks,
Naveen Kadian

variable i is defined in the Base class so any variable of this base type if was assigned a handle to an object of type Extended, it will be able access the i variable of it and will both point to the same i. so when you print b.i it prints 2 and your okay with that. when you call b.display() you are actually calling the disable of the base class but the integer i is updated after e.i=2 because as I said i was defined in the base class and both b and e are pointing to the same i. try to define another integer i inside Extended class and tell me what’s the result. and also why you are okay with b.i to be 2 but when b.display prints 2 you think this is wrong? display method prints the integer i of the class and also b.i use the i of this object which is the same integer i.

Hi @zeymou83 ,

SystemVerilog LRM, Chapter 8.14 Overridden Members says that when base class members are overridden in an extended class, references to base class handle access members of base class (it doesn’t matter if base is pointing to an extended object or not) (shown in Example 1).
If members are not overridden then after base = extended, references to base class handle access members of an extended class (because members are visible to b). So, in Example 2, only the display() method is overridden (which makes it invisible to b), which means references to b access base class method. So, accessing base class method via b (even b = e is done) should print the value of i as 1 instead 2.

try to define another integer i inside Extended class and tell me what’s the result.
Please check Example 2 where another i is defined in an extended class and it is working as expected as per SystemVerilog LRM Chapter 8.14.

and also why you are okay with b.i to be 2 but when b.display prints 2 you think this is wrong? display method prints the integer i of the class and also b.i use the i of this object which is the same integer i.
NK: I am okay with b.i to be 2 because this property is not overridden, so references to b.i will always access extended class property. So, my querry is how the value of extended class property i is visible in base class method because method is overridden, and b.display() should call base class method which can access only base class property.

Thanks,
Naveen Kadian

Hi @dave_59 ,

Could you please clarify why the value of I is printed as 2 when called b.display() after b = e; statement?

Thanks,
Naveen Kadian

The fact that you use the word “child” when referring to an extended class object suggests that you might be misinterpreting the notion that an extended class type is not an independent entity from its base class.

When extending a class type, the extended class inherits all the properties of the base classes it’s been extended from. When constructing an extended class, you get a handle to a single object that contains all the properties defined from the base class to the extended class type.

In example 2, you create two objects and store their handles in the class variables b and c. The object whose handle is in b has a variable Base::i and a method Base::display. Similarly, the object whose handle is in e also has a variable Base::i and methods Base::display and Extended::display.

After making the assignment b=e;, you are now left with only one class object, and both class variables, b and e, point to the same object, which is the Extended class object. Consequently, b.i and e.i refer to the same class member.

If that explanation doesn’t help clarify things for you, you should search for more tutorials on inheritance in SystemVerilog.

Hi @dave_59 ,

Thanks for your reply.

Corrected the use of word child in first message of this thread. I didn’t misinterpret about extended class, it is different and independent from its base class.

No need to refer other material. I understood well from your explanation and now know why the value of I is printed as 2.

Thanks again!!

Regards,
Naveen Kadian