C++ --重载, 覆盖 ,隐藏
第一、重载(overload)指函数名相同,但是它的参数表列个数或顺序,类型不同。但是不能靠返回类型来判断。其特征为:
- 相同的范围(在同一个作用域中) ;
- 函数名字相同;
- 参数不同;
- virtual 关键字可有可无。
- 返回值可以不同;
第二、重写(也称为覆盖 override)是指派生类重新定义基类的虚函数,特征是:
-
不在同一个作用域(分别位于派生类与基类) ;
-
函数名字相同;
-
参数相同;
-
基类函数必须有 virtual 关键字,不能有 static 。
-
返回值相同(或是协变),否则报错;
-
重写函数的访问修饰符可以不同。尽管 virtual 是 private 的,派生类中重写改写为 public,protected 也是可以的。
第三、重定义(也成隐藏)特征是:
-
不在同一个作用域(分别位于派生类与基类) ;
-
函数名字相同;
-
返回值可以不同;
-
参数不同。此时,不论有无 virtual 关键字,基类的函数将被隐藏(注意与重载以及覆盖混淆) 。
-
参数相同,但是基类函数没有 virtual关键字。此时,基类的函数被隐藏(注意与覆盖混淆) 。
给参考代码,便于理解
// Eclipse CDT and G++ #include <iostream> #include <complex> using namespace std; class Base { public: virtual void f(int){ cout<<"Base::f(int)"<<endl; } virtual void f(double){ cout<<"Base::f(double)"<<endl; } virtual void g(int){ cout<<"Base::g(int)"<<endl; } void h(int x){ cout<<"Base::h(int)"<<endl; } }; class Derived : public Base { public: // redefine the Base::f() function void f(complex<double>){ cout << "Derived::f(complex<double>)" << endl; } // override the Base::g(int) function void g(int x){ cout << "Derived::g(int)" << endl; } // redefine the Base::h() function void h(int){ cout << "Derived::h(int)" << endl; } }; int main() { Base base; Derived derived; Base* pb = new Derived; base.f(1.0); // Base::f(double) derived.f(1.0); // Derived::f(complex) pb->f(1.0); // Base::f(double), This is redefine the Base::f() function base.g(10); // Base::g(int) derived.g(10); // Derived::g(int) pb->g(10); // Derived::g(int), This is the virtual function delete pb; return 0; }输出结果:
Base::f(double) Derived::f(complex<double>) Base::f(double) Base::g(int) Derived::g(int) Derived::g(int)通过上述的代码和输出结果,不难可以看出,
第一、Base类中的第二个函数f是对第一个的重载;
第二、Derived类中的函数g是对Base类中函数g的重写,即使用了虚函数特性。
第三、Derived类中的函数f是对Base泪中函数f的隐藏,即重定义了。
第四、pb指针是一个指向Base类型的指针,但是实际指向了一个Derived的空间,这里对pd调用函数的处理(多态性)取决于是否重写(虚函数特性)了函数,若没有,则依然调用基类。
第五、只有在通过基类指针或基类引用 间接指向派生类类型时多态性才会起作用。因Base类的函数h没有定义为virtual虚函数,所以Derived类的函数h是对Base::h()的重定义。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。