C++ --重载, 覆盖 ,隐藏

刚从网上看点C++东东写的不错。在此,结合自己所理解地,整理整理C++中重载(overload), 覆盖(override)和隐藏概念。

第一、重载(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()的重定义。



郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。