override/overwrite/overload的区别
(1)overload——重载
- 允许在同一作用域内有多个同名不同参的函数(这里的作用域可以是命名空间也可以指的一个class)。
(1)当我们在同一作用域内定义了多个名字相同的函数之后,编译器会通过名字修饰(name decoration)的方式将这些函数名修改成可以唯一标识的形式,简单的说就是背地里偷偷地将函数名给改了;
(2)同名函数经过一番加工之后,对函数的调用就会根据函数的参数类型和参数个数等链接到正确的函数入口,从而实现正确的函数调用;
(3)虽然函数overload是一种好的特性,但在SV语言中是不支持的;
举例
//****************************编译报错****************************
class A;
function void print(int number);
$display("The number is %0d", number);
endfunction
function void print(string name);
$display({"My name is ", name});
endfunction
endclass
module tb;
A a_inst;
initial begin
a_inst = new();
a_inst.print(66);
a_inst.print("CC");
end
endmodule
(2)overwrite——重写
- overwrite发生在子类和基类之间,即不同的类域之间。overwrite发生在同名函数中,同不同参无所谓。
(1)发生overwrite的函数必须是非虚函数,因为一旦基函数被声明为虚函数,调用同名函数时会发生多态(会根据对象类型来决定调用基类中的还是子类中的同名函数),当这些条件满足的时候,我们就说这个函数被overwrite了;
(2)在调用被overwrite的函数时,会根据句柄的类型(而不是对象的类型)决定调用基类中的还是子类中的同名函数(与override会有明显的区别);
(3)override——覆盖
- override发生在子类和基类之间的同名同参函数身上,并且该同名函数在基类中要求被声明为虚函数。
(1)和overwrite的区别就是多了函数参数相同和基类中必须为虚函数这两个要求,当这些条件都满足时,就可以认为这个函数在类间被override了;
(2)当发生override的函数被调用的时候,会根据句柄指向的对象类型来动态地决定要调用基类中还是子类中的同名函数(与多态性结合);
举例
class A;
function void print_1(string str);
$display({str,": not virtual function 1 in class A"});
endfunction
virtual function void vri_print_1(string str);
$display({str,": virtual function 1 in class A"});
endfunction
function void print_2(string str);
$display({str,": not virtual function 2 in class A"});
endfunction
virtual function void vir_print_2(string str);
$display({str,": virtual function 2 in class A"});
endfunction
end
class B extends A;
function void print_1(string str);
$display({str,": not virtual function 1 in class B"});
endfunction
virtual function void vri_print_1(string str);
$display({str,": virtual function 1 in class B"});
endfunction
function void print_2(int number);
$display("%d: not virtual function 2 in class B", number);
endfunction
// Error override必须是同名同参的虚函数
// virtual function void vir_print_2(int number);
// $display("%d: virtual function 2 in class A", number);
// endfunction
endclass
module tb;
A a_inst_1;
A a_inst_2;
B b_inst_1;
initial begin
a_inst_1 = new();
b_inst_1 = new();
a_inst_2 = b_inst_1; // 多态性
$display("The object address of a_inst_1: %h", a_inst_1);
$display("The object address of b_inst_1: %h", b_inst_1);
$display("The object address of a_inst_2: %h", a_inst_2);
$diaply("*************************************");
a_inst_1.print_1("a_inst_1");
b_inst_1.print_1("b_inst_1");
a_inst_2.print_1("a_inst_2");
$diaply("*************************************");
a_inst_1.vri_print_1("a_inst_1");
b_inst_1.vri_print_1("b_inst_1");
a_inst_2.vri_print_1("a_inst_2");
$diaply("*************************************");
a_inst_1.print_2("a_inst_1");
b_inst_1.print_2(666);
a_inst_2.print_2("a_inst_2");
end
endmodule
//*************************run_result**************************
// The object address of a_inst_1: f0568842
// The object address of a_inst_1: f0568870
// The object address of a_inst_1: f0568870
//***************************************************
// a_inst_1: not virtual function 1 in class A
// b_inst_1: not virtual function 1 in class B
// a_inst_2: not virtual function 1 in class A
//***************************************************
// a_inst_1: virtual function 1 in class A
// b_inst_1: virtual function 1 in class B
// a_inst_2: virtual function 1 in class B
//***************************************************
// a_inst_1: not virtual function 2 in class A
// 666: not virtual function 2 in class B
// a_inst_2: not virtual function 2 in class A
summary
- overload在SV中不支持;
- overwrite发生在不同类域的同名非虚函数之间;
- override发生在不同类域的同名同参的虚函数之间。