c++中重载、隐藏和覆盖的区别

12 篇文章 0 订阅
6 篇文章 0 订阅

一、三者的定义

1.重载

重载分为普通函数重载、运算符重载和类型重载,在这里我们只介绍普通函数重载,包括全局作用域下的函数重载和类作用域下的函数重载。
(1)函数名相同
(2)参数列表相同(包括参数个数、参数类型和参数顺序)
(3)属于同一作用域(必须是在同一个类中的成员函数或者均为全局函数,即基类和派生类中的同名函数不可能构成重载)

2.覆盖

(1)函数名相同
(2)发生在基类和派生类之间(这里的基类可能不是直接基类)
(3)基类的成员函数必须定义为虚函数(必须用virtual修饰),派生类中的成员函数可以不用virtual修饰(因为会自动从基类继承virtual特性)

3.隐藏

(1)函数名相同
(2)发生在基类和派生类之间
(3)基类中的成员函数没有被virtual修饰,此时不管派生类中的成员函数是否与基类成员函数列表相同,两者都构成隐藏关系
(4)基类的中成员函数被virtual修饰,但是此时派生类中的成员函数和基类成员函数列表不同,两者构成隐藏关系

二、举例说明三者的区别

下面以一个具体的例子来对以上三者进行说明:

class Base
{
public:
    Base() :mem(0)
    {

    }

    virtual int memfun()  //1
    {
        cout << "Base::memfun()" << endl;
        return 0;     
    }
protected:
    int mem;
};

class Derive1 :public Base
{
public:
    Derive1(int i = 0) :mem(i)
    {

    }   
    int memfun(int a)  //2
    {       
        cout<<"Derive1::memfun()"<<endl;
        return a;
    }
    virtual void f2()  //3
    {
        cout << "Derived::f2()" << endl;
    }

protected:
    int mem;
};

class Derive2 :public Derive1
{
public:
    int memfun()  //4
    {
        cout << "Derive2::memfun()" << endl;
        return 1;
    }
    int memfun(int a)  //5
    {
        cout << "Derive2::memfun(int)" << endl;
        return 3;  
    }
    void f2()  //6
    {
        cout << "Derive2::f2()" << endl;
    }
};

这个例子比较复杂,我们先来梳理一下各个类的内存布局情况:
这里写图片描述
(1).1和2构成隐藏关系,2隐藏1.即通过Derive1的对象无法调用无参数的memfun函数。
(2).1和4构成覆盖关系,因为类Derive2的间接基类为Base,且Derive2中的memfun()函数和Base的memfun()函数满足上面所说的构成覆盖关系的特点。
(3).1和5构成隐藏关系,5将1隐藏了。即通过Derive2的对象无法调用无参数的memfun函数
(4).2和4、2和5均构成隐藏关系
(5).4和5构成重载关系
(6).3和6构成覆盖关系

下面根据上面类的定义,说明一下如何调用以上函数:

int main(void)
{
    Base bobj;
    Derive1 d1obj;
    Derive2 d2obj;
    Base *bp1 = &bobj;
    Base *bp2 = &d1obj;
    Base *bp3 = &d2obj;

    bp1->memfun();  //Base::memfun
    bp2->memfun();  //Base::memfun
    bp3->memfun();  //Derive2::memfun

    Derive1 *d1p = &d1obj;
    Derive2 *d2p = &d2obj;
    //bp2->f2();        //错误,Base没有名为f2的成员函数
    d1p->f2();      //调用D1::f2
    d2p->f2();      //调用Derive2::f2

    Base*p1 = &d2obj;
    Derive1 *p2 = &d2obj;
    Derive2 *p3 = &d2obj;

    //p1->memfun(42);   //错误,Base中没有一个接受int的memfun
    p2->memfun(32); //静态绑定,调用Derived::memfcn(int)
    p3->memfun(23); //静态绑定,调用Derive2::memfcn(int)
    return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值