Create() in the advantages from a hardcoding perspective only

I’m trying to understand how much create() have the benefits instead new().

So I make a simple example to compare between them.

This is created by new() method.


// Define a base class
class my_base_class extends uvm_object;

  // Define some virtual methods
  virtual function void do_something();
    // Implementation not shown
  endfunction

endclass

// Define a derived class
class my_derived_class_1 extends my_base_class;

  // Override the virtual method
  virtual function void do_something();
    // Implementation not shown
  endfunction

endclass

// Define another derived class
class my_derived_class_2 extends my_base_class;

  // Override the virtual method
  virtual function void do_something();
    // Implementation not shown
  endfunction

endclass

// In the testbench, create objects of different types using new()
module my_testbench;

  // Create an object of my_derived_class_1
  my_base_class* obj1 = new my_derived_class_1();
  
  // Create an object of my_derived_class_2
  my_base_class* obj2 = new my_derived_class_2();

  // Call a virtual method on the objects
  obj1.do_something();
  obj2.do_something();

endmodule

This is created by create() method.

// Define a base class
class my_base_class extends uvm_object;

  // Define some virtual methods
  virtual function void do_something();
    // Implementation not shown
  endfunction

endclass

// Define a derived class
class my_derived_class_1 extends my_base_class;

  // Override the virtual method
  virtual function void do_something();
    // Implementation not shown
  endfunction

endclass

// Define another derived class
class my_derived_class_2 extends my_base_class;

  // Override the virtual method
  virtual function void do_something();
    // Implementation not shown
  endfunction

endclass

// In the testbench, create objects of different types at runtime
module my_testbench;

  // Create an object of my_derived_class_1
  my_base_class* obj1 = my_derived_class_1::type_id::create("my_derived_class_1", null);
  
  // Create an object of my_derived_class_2
  my_base_class* obj2 = my_derived_class_2::type_id::create("my_derived_class_2", null);

  // Call a virtual method on the objects
  obj1.do_something();
  obj2.do_something();

endmodule

From verificationacademy.com, the create() allows type overriding during runtime and no need to modify the code .

I’m curious as to what the advantages are from a hardcoding perspective only.

In reply to UVM_LOVE:

I’m not sure what you mean by “from a hardcoding perspective only”.

If you never plan on allowing someone to override a class type with the factory, there is no point in registering the class with the factory using the `uvm_object_utils macro, and, using the creste() method. Both impose some small but measurable performance impact.

The benefit of the factory’s create method becomes much more obvious when there are more levels of construction involved and you want to override a class from the top level test. For example, a test constructs an env, which constructs an agent, which starts a sequence, which sends a sequence_item. Without the factory, if you wanted to extend the sequence_item in one of your tests, and still have other tests that used the original sequence_item, you would either have to modify your sequence to know every possible sequence_item it could construct, or modify all classes in the chain of construction up to the top level to construct the derived sequence_item.

You should try creating a few examples of this.