C++ 重载、覆盖与隐藏

首先看下这三个概念(http://www.cnblogs.com/fangyukuan/archive/2010/09/18/1829871.html 34题):
a.成员函数被重载的特征:
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。
b.覆盖是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual 关键字。
c.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)

重载和覆盖很好区分,然而隐藏具体而言是什么意思呢?
根据上述规则,以下情况发生了隐藏:

class Parent{
public:
    void f1(){
        cout << "Parent::f1\n";
    }
    void f2(){
        cout << "Parent::f2\n";
    }
};
class Child : public Parent{
public:
    void f1(){
        cout << "Child::f1\n";
    }
    void f2(int x){
        cout << "Child::f2\n";
    }
};

Child::f1()和Child::f2(int)分别隐藏了Parent::f1()和Parent::f2()
注意如果Parent::f1()是virtual的,则变成了覆盖
试着调用f1与f2:

Parent *p = new Child();
Child *c = new Child();
p->f1();
p->f2();
p->f2(1);//错误:函数中调用的参数太多
c->f1();
c->f2();//错误:函数中调用的参数太少
c->f2(1);

编译成功的部分输出为:

Parent::f1
Parent::f2
Child::f1
Child::f1

综上,我们可以发现:
a.发生隐藏时,虽然p指针指向的是Child的实例,但调用p->f1()时调用的不是Child的f1,而是Parent的f1
b.p指针无法调用Child::f2(int)
c.c指针无法调用Parent::f2()

因此,总结一下,在覆盖中,用基类指针和派生类指针调用函数f1()时,系统都是执行的派生类函数f1(),而非基类的f1(),调用函数由指针指向的实例决定,这样实际上就是完成“接口”的功能。
而在隐藏中,用基类指针和派生类指针调用函数f1()时,系统会进行区分,基类指针调用时,系统执行基类的f1(),而派生类指针调用时,系统“隐藏”了基类的f1(),执行派生类的f1(),也就是由指针的类型决定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值