How to mimic static constructor in SystemVerilog?

I have a parent class and a lot of child classes. And I want to instantiate all the child classes and cast them into a parent object array/queue so I can do something useful things using the parent array/queue.

The code is below:


class parent;
endclass

class child1 extends parent;
endclass

class child2 extends parent;
endclass

program top;

    child1  c1;
    child2  c2;
    parent p, p_arr[$];

    initial
    begin
      c1 = new;
      assert ($cast(p,c1)) else $fatal;
      p_arr.push_back(p);
      c2 = new;
      assert ($cast(p,c2)) else $fatal;
      p_arr.push_back(p);

      // Doing useful things with p_arr
      // .......
    end
endprogram

I wonder if there is a way make this more tidy. So I change my code into this:


    begin
      assert ($cast(p,child1.new())) else $fatal;   <---- compiler complain about "child1::new"
      p_arr.push_back(p);

      assert ($cast(p,child2.new())) else $fatal;
      p_arr.push_back(p);
    end    

But the compiler complains about directly using static constructor “child1.new()”. Does SystemVerilog support such a feature? If not, is there is tidy way to do it? For example using macro?

The problem with macro is that I have to use two macros to do it. One macro declares the instance at the top of the function/program first:


child1  c1; 

And then another macro initializes the instance and put itinto array in the body of the function/program:


c1 = new;
assert ($cast(p,c1)) else $fatal;
p_arr.push_back(p);

Is there a way to use one macro to do this instead of two macro?

In reply to Ty Lee:

The SystemVerilog BNF requires that new() appear on the RHS of an assignment. But there’s no need to use $cast when making an assignment from an extended class to a base class variable. So you can do:

module top;
    parent p, p_arr[$];
    initial
      begin
	 p = child1::new();
	 p_arr.push_back(p);
	 p = child2::new();
	 p_arr.push_back(p);
	 
	 // Doing useful things with p_arr
	 // .......
    end
endmodule

You can also do things like

 p_arr = '{3{null}};
         p_arr[0] = child1::new();
         p_arr[1] = child2::new();
         p_arr[2] = child1::new();

Thanks. This worked for me.

p = child1::new();