是否可以将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
答案 0 :(得分:4)
是的,您可以通过创建一个对象来完成此操作,该对象充当您要创建的类型的代理。这种代码模式在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
我有a paper详细解释了这个工厂模式代码的更多信息。
答案 1 :(得分:0)
我的一位同事建议这种解决方案类似于戴夫的建议。
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