一张图讲明白重载、覆盖和隐藏的联系与区别!

学到类的继承这边会出现三个容易混淆的概念:重载(overload)、覆盖(override)和隐藏(hide)。

  • 重载:同一作用域内的几个函数名字相同但参数列表不同(见C++ Primer 6.4节)。
  • 覆盖:派生类对基类中有相同函数签名(指参数列表+返回类型)的函数进行重定义(来自GeeksforGeeks,见C++ Primer 15.2-3节)。
  • 隐藏:内作用域的函数会使外作用域的函数变得不可见。

如何厘清这三者之间的关系?给定两个函数,如何判断他们是重载/覆盖/隐藏?看下面这张图就够了。

在这里插入图片描述

按照上图的判断过程,可以轻松判断main 函数中每一行代码的输出。

#include <iostream>

using std::cout;

struct Base
{
    void f() { cout << "Base f\n"; }
    void f(char) { cout << "Base f char\n"; }
    void f(int) { cout << "Base f int\n"; }
    virtual void g(char) { cout << "Base g char\n"; }
    virtual void g(int) { cout << "Base g int\n"; }
    virtual void h() { cout << "Base h\n"; }
};

struct Derived : public Base
{
    void f() { cout << "Derived f\n"; }
    void f(char) { cout << "Derived f char\n"; }
    void f(double) { cout << "Derived f double\n"; }
    virtual void g() { cout << "Derived g\n"; }
    virtual void g(char) { cout << "Derived g char\n"; }
    virtual void g(double) { cout << "Derived g double\n"; }
    virtual int h() { return 1; } // 如果参数列表相同,必须保证返回类型也相同,才能覆盖;如果返回类型不同,必须保证参数列表也不同,才能隐藏。
    //error: conflicting return type specified for 'virtual int Derived::h()'
    using Base::f;  // 使被基类被隐藏的f变得可见
};

int main()
{
    Derived d;
    Base *bp = &d;
    d.f();  // Derived f
    d.f(1);  // Base f int
    cout << "====\n";
    bp->f();  // Base f
    bp->f(1);  // Base f int
    cout << "====\n";
    d.g(1.1);  // Derived g double
    d.g('a');  // Derived g char
    d.g(1); // 二义性调用,参数是char还是double? error: virtual void Derived::g(char) or virtual void Derived::g(double)
    cout << "====\n";
    bp->g(); // 静态类型为基类基类没有名为g的函数不接受参数。error: candidate expects 1 argument, 0 provided
    bp->g('a');  // Derived g char
    bp->g(1);  // Base g int
    bp->g(1.1); //静态类型为基类,二义性调用,参数是char还是int? error: virtual void Base::g(char) or virtual void Base::g(int)
    cout << "====通过作用域运算符调用另一函数\n";
    d.Base::f();  // Base f
    bp->Base::g('a');  // Base g char
    return 0;
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值