美文网首页
重载、覆盖、隐藏

重载、覆盖、隐藏

作者: 爱秋刀鱼的猫 | 来源:发表于2017-06-21 10:16 被阅读0次
    一、重载(overload):
       特征: 函数名相同 、函数参数不同、 必须位于同一个域(类)中; 
    

    注意,返回值类型不相同,不能作为重载的判断条件。

    二、覆盖(override):
       特征: 函数名相同 、函数参数相同、 分别位于派生类和基类中、virtual(虚函数); 
    
    三、隐藏(hide/Overwrite(重写)):
        即:派生类中函数隐藏(屏蔽)了基类中的同名函数。
    

    情形1: 函数名相同、 函数参数相同、 分别位于派生类和基类中、virtual -- 为 覆盖;

    情形2: 函数名相同、 函数参数相同、 分别位于派生类和基类中 -- 为 隐藏;(即跟覆盖的区别是基类中函数是否为虚函数)

    情形3: 函数名相同、 函数参数不同、 分别位于派生类和基类中 -- 为 隐藏;(即与重载的区别是两个函数是否在同一个域(类)中)

    小结
    首先:重载必须在同一个作用域当中讨论。覆盖和隐藏则是在基类和子类中。
    其次:对于某个虚函数,如果子类参数相同,就是覆盖,否则就是隐藏。
    最后:对于非虚函数而言,函数名相同就是为隐藏。
    为了巩固知识点,可以做一下下面这道题:

    class parent
    {
    public:
        virtual void foo(){cout<<"foo from parent"<<endl;}
        void foo1(){cout<<"foo1 from parent"<<endl;}
    
    };
    class son:public parent
    {
    public:
        void foo(){cout<<"foo from son"<<endl;}
        void foo1(){cout<<"foo1 from son"<<endl;}
    
    };
    int main()
    {
        parent *p=new son();
        p->foo();
        p->foo1();
        system("pause");
        return 0;
    }
    

    不知道你们的答案是什么,我第一次做的答案是:foo from son;foo1 from son
    如果你放到VS当中去运行一下,得到的结果是:


    运行结果

    第一条输出没有问题,是一个虚函数的覆盖问题,考察的是动态绑定这个知识点,但是第二条输出就有两种解释:

    对于输出foo1 from son,观点是,在son这个类中,我们对foo1这个函数进行了重写,这样的隐藏了parent类里的foo1,加上我们没有使用using声明式,使得parent::foo1()函数在son中可见,所以应该调用的是son::foo1()
    对于输出foo1 from parent,观点是,非虚函数是静态绑定的,p的静态类型是parent,所以应该调用的是parent::foo1()
    这就相互矛盾了。所以在实际编码过程中,绝对不要重新定义继承而来的非虚函数,不然你就是自己给自己找麻烦。至于出这道题的公司,我觉得应该下一次挑一个实战性选手:D

    相关文章

      网友评论

          本文标题:重载、覆盖、隐藏

          本文链接:https://www.haomeiwen.com/subject/djyzqxtx.html