Nested instantiations of the same class

Hi, I am digging into the source cod eof uvm1.2, in an effort to create a mental graph for myself about the implementation. I am encountered with this piece fo code in uvm_port_base.svh


virtual class uvm_port_base #(type IF=uvm_void) extends IF;
   

  typedef uvm_port_base #(IF) this_type;
  
  // local, protected, and non-user properties
  protected int unsigned  m_if_mask;
  protected this_type     m_if;    // REMOVE
  protected int unsigned  m_def_index;
  uvm_port_component #(this_type) m_comp;
  local this_type m_provided_by[string];
  local this_type m_provided_to[string];
  local uvm_port_type_e   m_port_type;
  local int               m_min_size;
  local int               m_max_size;
  local bit               m_resolved;
  local this_type         m_imp_list[string];

Does this mean that the class uvm_port_base#(IF) has a nested uvm_port_base#(IF) instantiation “m_if”? I was under the impression that such code will create an indefinitely nested loop, and shouldn’t be able to compile. Furthermore, there are associative arrays m_provided_by, and m_proved_to. How do we get away with the indefinite-Russian-doll kind of situation?
It would also be greatly appreciated if anyone can illustrated why this is necessary or this facilitate anything. :)

In reply to chuncheng:
Declaring a class variable of the same type you are defining does not create recursive instances; it just creates a variable that can hold a handle to another object of the same type. You would only get into a recursive situation if the construction of the class calls another constructor of itself.

There are many kinds of data structures that use this technique, like linked lists and trees. The uvm_component class contains class variables that link to its parent as well as an array for its children.

I explain this with an example in the first session of my SystemVerilog OOP class.

In reply to dave_59:
Thanks a lot. I now understand this concept. I was originally confused with C++ like oop where

class TEST {
 TEST x_test;
}

is causing the infinite recursive instance. The c++ oop counterpart here is probably similar to

class TEST {
 TEST* x_test;
}