C++ 函数的重载,覆盖及隐藏解析

来源:互联网 发布:java 教程哪个好 编辑:程序博客网 时间:2024/05/01 11:38

C++ 函数的重载,覆盖及隐藏

一、函数重载的解析

      1、重载函数是函数的一种特殊情况,为方便使用,C++允许在同一范围中声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同,也就是说用同一个运算符完成不同的运算功能。这就是重载函数。重载函数常用来实现功能类似而所处理的数据类型不同的问题。
两个重载函数必须在下列一个或两个方面有所区别:
        1.)、函数有不同参数。
        2.)、函数有不同参数类型,
       

       2、重载函数被重载的特征:

       1)相同的范围(在同一个类中)

       2)函数名字相同;

       3)参数不同;

       4)virtual 关键字可有可无。

二、覆盖函数解析

        1、覆盖(也叫重写)只对类的构造函数或成员函数适用,是子类继承父类是才使用的非常有用的功能。真正和多态相关。它们的地址在编译时无法确定,在运行时动态分配

        2、覆盖函数的特征是:
        1)不同的范围(分别位于派生类与基类)
        2)函数名字相同;
        3)参数相同
        4)基类函数必须有virtual 关键字

三、函数隐藏解析

       1、是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
       1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
       2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。

四、函数举例

例1:举例说明函数覆盖和函数重载的关系

class Base
{
public:
    void Walk(int x){ cout <<"Base::Walk(int)"<< endl; }
    void Walk(float x){cout<<"Base::Walk(float)"<<endl;}
    virtual void Run(void){cout<<"Base::Run(void)"<<endl;}
};

class Derived: public Base
{
public:
    virtual void Run(void){cout<<"Derived::Run(void)"<<endl;}
};

// 如上关系是:Base::Walk(float)和Base::Walk(int)是函数重载关系
                        Derived::Run(void)覆盖了Base::Run(void),而不是虚函数重载

int main()
{
    Derived der;
    Base *pb = &der;
    pb->Walk(20);      // 调用 Base::Walk(int)
    pb->Walk(1.2f);    // 调用 Base::Walk(float)
    pb->Run();         // 调用 Derived::Run(void)
    return 0;
}


例2:举例说明函数隐藏的关系

class Base
{

public:
    virtual void Walk(){ cout <<"Base::Walk()"<< endl; }
    void Run(float x){cout<<"Base::Run(float)"<<endl;}
};


class Derived: public Base
{
public:
    virtual void Walk(int x){ cout <<"Derived::Walk(int)"<< endl; }
    void Run(int x){cout<<"Derived::Run(int)"<<endl;}
};
如上的关系是 Derived::Walk(int)隐藏了函数Base::Walk()
Derived::Run(int) 隐藏了Base::Run(float),而不是重载(不在同一个作用域内),也不是覆盖,因为函数不是虚函数



int main()
{
    Derived der;
    Derived* pd = &der;
    pd->Run(1);         // 调用Derived::Run(int)
    pd->Run(1.2f);    // 调用Derived::Run(int)   证明Base::Run(float)被隐藏
    pd->Walk(1);      //  Derived::Run(int)"
    // pd->Walk();     //编译无法通过,函数被隐藏
    Base *pb = &der;
    pb->Run(1);       // 调用Base::Run(float)
    pb->Run(1.2f);    // 调用Base::Run(float) 
    pb->Walk();
    //pb->Walk(1);     //编译不能通过,函数被隐藏
    return 0;
}