加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

C++覆盖,隐藏,重载

发布时间:2020-12-16 10:48:09 所属栏目:百科 来源:网络整理
导读:? 定义 函数覆盖 (1) 作用域不同 (2) 有virtual关键字 (3) 参数列表/返回值/调用约定必须相同 函数隐藏 (1) 作用域不同 (2) 函数名相同 (3) 参数列表/返回值/调用约定不考虑 函数重载 (1) 作用域相同 (2) 函数名相同 (3) 参数列表不同,返回值/调用约定不考

?

定义

  • 函数覆盖
    (1) 作用域不同
    (2) 有virtual关键字
    (3) 参数列表/返回值/调用约定必须相同
  • 函数隐藏
    (1) 作用域不同
    (2) 函数名相同
    (3) 参数列表/返回值/调用约定不考虑
  • 函数重载
    (1) 作用域相同
    (2) 函数名相同
    (3) 参数列表不同,返回值/调用约定不考

练习

class Base
{
public:
    virtual void Handle1(float x)
    {
        cout << "Base::Handle1(float) " << x << endl;
    }
    void Handle2(float x)
    {
        cout << "Base::Handle2(float) " << x << endl;
    }
    void Handle3(float x)
    {
        cout << "Base::Handle3(float) " << x << endl;
    }
};

class Derived : public Base
{
public:
    virtual void Handle1(float x)
    {
        cout << "Derived::Handle1(float) " << x << endl;
    }
    void Handle2(int x)
    {
        cout << "Derived::Handle2(int) " << x << endl;
    }
    void Handle3(float x)
    {
        cout << "Derived::Handle3(float) " << x << endl;
    }
    void Handle3(double x)
    {
        cout << "Derived::Handle3(double) " << x << endl;
    }
};

观察以上类声明及实现,试预测以下main中的执行结果,注意两点:

  1. 调用的方法是哪个?
  2. 调用造成的原因,是重载、覆盖、隐藏中的哪一种?
 void main(void)
 {
     Derived DervObj;
     Base *pBase = &DervObj;   
     Derived *pDerv = &DervObj;
 
     pBase->Handle1(3.14f);
     /******************************************
     预测:
           输出Derived::Handle1(float)3.14
           是间接调用,覆盖
     运行结果:Derived::Handle1(float)3.14
     ******************************************/
 
 
     pDerv->Handle1(3.14f);
     cout << endl;
     /******************************************
     预测:
           输出Derived::Handle1(float)3.14
           是间接调用,隐藏
     运行结果:Derived::Handle1(float)3.14
     ******************************************/
 
 
     pBase->Handle2(3.14f);
     /*****************************************
     预测:
           输出Base::Handle2(float)3.14
           是直接调用,隐藏
     运行结果:Base::Handle2(float)3.14
     *****************************************/
 
 
 
     pDerv->Handle2(3.14f);
     /****************************************
     预测:
           输出Derived::Handle2(int)3
           是直接调用,隐藏
     运行结果:Derived::Handle2(int)3
     *****************************************/
     cout << endl;
 
 
 
     pBase->Handle3(3.14f);
     /****************************************
     预测:
           输出Base::Handle3(float)3.14
           直接调用,隐藏
     结果:Base::Handle3(float) 3.14
     }
     ****************************************/
 
 
     pDerv->Handle3(3.14f);
     /***************************************
       预测:输出Derived::Handle3(float)3.14
             直接调用,隐藏
       结果:Derived::Handle3(float) 3.14
     }
     ***************************************/
 
 
     pDerv->Handle3(3.14);
     /**************************************
       预测:输出Derived::Handle3(double)3.14
             直接调用,隐藏
       结果:Derived::Handle3(double) 3.14
     **************************************/
     cout << endl;
     
     pDerv->Handle3(3);
     /****************************************
       Handle3没有对应的整数形参,只有float和double
       3既可以转换为float,又可以转换为double,所以编译时报错。
     /****************************************/
     system("pause");
 }

总结

当覆盖,隐藏,重载同时存在时,如何确定调用了某个类的某个函数? a)查看调用该函数的数据类型,并找到该类型的作用域(函数隐藏) b)在该作用域中找到同名函数,满足参数列表相同(可以做适当的类型转换),在从这些同名函数中选出最佳的, 如果有多个则产生二义性(函数重载) c)查看选出的最佳匹配函数是否是虚函数,如果是虚函数并且调用该虚函数的数据类型为指针或引用, 那么就是间接调用,否则就是直接调用(函数覆盖)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读