重载(overload), 覆盖(override), 隐藏(hide)的区别

[TOC]
正文开始之前,首先介绍一下3个关键字对应的英文:重载(overload), 覆盖(override), 隐藏(hide)。
下面我们依次介绍。

  1. 隐藏(hide),直接看代码
#include <iostream>
using namespace std;
class CB {
public:
    void f(int i) {
        cout << "CB::f(int)" << endl;
    }
};
class CD: public CB {
public:
    void f(int i, int j) {
        cout << "CD::f(int, int)" << endl;
    }
    void test() {
        f(1);
    }
};
int main () {
    CB B;
    CD D;
    B.f(1);
    D.test();
    return 0;
}

编译出错:error: no matching function for call to ‘CD::f(int)’|
因此,我们得到结论类CD中并不存在f(int) 函数,因为基类void CB::f(int)被子类void CD::f(int, int) 隐藏。
如果把派生CD中成员函数void f(int,int)的声明改成和基类中一样,即f(int),基类中的void f(int)还是一样被覆盖,此时编译不会出错,在函数中test调用的是CD中的f(int) 
所以,在基类中的某些函数(e.g., f())如果没有关键字virtual修饰,那么子类中的同名函数(e.g., f(), 形参和返回值可以不同)会将基类中同名函数隐藏。
2. 覆盖(override),对上面代码稍作修改:

#include <iostream>
using namespace std;
class CB {
public:
    virtual void f(int i) {
        cout << "CB::f(int)" << endl;
    }
};

class CD: public CB {
public:
    virtual void f(int i) {
        cout << "CD::f(int)" << endl;
    }
    void test() {
        f(1);
    }
};

int main () {
    CB B;
    CD D;
    CB *C = &D;
    CD *E = (CD*) &B;
    C->f(3);
    E->f(3);
    return 0;
}

程序编译成功,运行结果如下:多态
这是很简单的多态应用,详细可参考上一篇博客. 这样的情况我们成为覆盖,指派生类的虚拟函数覆盖了基类的同名且形参和返回值一样的函数。
因此覆盖需要满足如下两个条件:
- 有virtual关键字,在基类中函数声明的时候加上就可以了
- 基类CB中的函数和派生类CD中的函数要一模一样,什么叫一模一样,函数名,参数,返回类型三个条件。
3. 重载
很多人会将上述两种情况误认为重载,这是因为对重载概念不清晰,我们再次详述重载的概念:
重载(overload):必须在一个域中,函数名称相同但是函数参数不同,重载的作用就是同一个函数有不同的行为,因此不是在一个域中的函数是无法构成重载的,这个是重载的重要特征必须在一个域中,而继承明显是在两个类中了哦,所以上面的想法是不成立的,我们测试的结构也是这样,派生类中的f(int,int)把基类中的f(int)隐藏了。所以,相同的函数名的函数,在基类和派生类中的关系只能是覆盖或者隐藏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值