传递“type”参数给函数

4

是否可以向函数传递 type 参数,以便通过将类类型参数传递给它来仅一次编写 create_eclass * 函数?

class bclass;

virtual function void print();
    $display("Base Class");
endfunction

endclass

class eclass1 extends bclass;

    function void print();
        $display("Extended Class1");
    endfunction

endclass

class eclass2 extends bclass;

    function void print();
        $display("Extended Class2");
    endfunction
endclass

program Test ;
    bclass q[$];

    function create_eclass1();
        bclass     b;
        eclass1    e;
        e=new();
        $cast(b,e);
        q.push_back(e);
    endfunction

    function create_eclass2();
        bclass     b;
        eclass2    e;
        e=new();
        $cast(b,e);
        q.push_back(e);
    endfunction

    initial
    begin
        create_eclass1();
        create_eclass2();
        foreach(q[i]) q[i].print();
    end
endprogram
2个回答

5
是的,您可以通过创建一个充当所需创建类型代理的对象来实现这一点。这种代码模式在UVM工厂中使用。
typedef bclass; // this would be uvm_object in the UVM

interface class object_wrapper; // like a virtual class except it only contains pure virtual methods
   pure virtual function bclass create;
endclass
   
class object_registry#(type T) implements object_wrapper;
   typedef object_registry#(T) this_type;
   local static this_type _singleton; // only one object for each class type
   local function new;
   endfunction
   static function object_wrapper get;
      if (_singleton == null) _singleton = new;
      return _singleton;
   endfunction // if
   virtual function T create;
      create = new;
   endfunction
endclass

这段代码的其余部分与您原始示例中的代码基本相同。我只是通过添加typedef来注册类,这会导致object_registry中的静态变量和方法出现。
class bclass;

   virtual function void print();
      $display("Base Class");
   endfunction
   
endclass
   
class eclass1 extends bclass;
   typedef object_registry#(eclass1) type_id;
   
   function void print();
      $display("Extended Class1");
   endfunction
   
endclass
   
class eclass2 extends bclass;
   typedef object_registry#(eclass2) type_id;
   function void print();
      $display("Extended Class2");
   endfunction
endclass
   
module Test ;
   bclass q[$];
   
   function void create_eclass(object_wrapper h);
      q.push_back(h.create());
   endfunction

   object_wrapper a1,a2;
   
   initial
     begin   
        create_eclass(eclass1::type_id::get() );
        create_eclass(eclass2::type_id::get() );
    // or another way - 
    a1 = eclass1::type_id::get();
    a2 = eclass2::type_id::get();
        create_eclass(a1 );
        create_eclass(a2 );
        create_eclass(a2 );
        create_eclass(a1 );
    
        foreach(q[i]) q[i].print();
     end
endmodule

我有一篇详细解释这个工厂模式代码的论文。

是的。我只是加入了UVM连接,因为你标记了它。 - dave_59
一条链接可能已经损坏 - Carter
@Carter 更新了链接 - dave_59

1
我的一位同事建议了一个与Dave提出的类似的解决方案。
virtual class eclass_creator #( type T = bclass );
  static function T create(int k) ;
    create = new(k) ;
  endfunction
endclass

这样可以创建一个作用域构造函数。

class bclass;
    int i;
    function new(int k);
        i=k;    
    endfunction
    virtual function void print();
        $display("Base Class %0d",i);
    endfunction
endclass

class eclass1 extends bclass;
    function new(int k);
        super.new(k);    
    endfunction
    function void print();
        $display("Extended Class1 %0d",i);
    endfunction
endclass

class eclass2 extends bclass;
    function new(int k);
        super.new(k);    
    endfunction
    function void print();
        $display("Extended Class2 %0d",i);
    endfunction
endclass

program Test ;
    bclass q[$];

    function void push(bclass inclass);
       q.push_back(inclass);
    endfunction

    initial
    begin
        push(eclass_creator #(eclass1)::create(5));
        push(eclass_creator #(eclass2)::create(10));
        foreach(q[i]) q[i].print();
    end
endprogram

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接