重载、覆盖、隐藏

一、重载(overload):
   特征: 函数名相同 、函数参数不同、 必须位于同一个域(类)中; 

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

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

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

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

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

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

class parent
{
public:
    virtual void foo(){cout<<"foo from parent"<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

你可能感兴趣的:(重载、覆盖、隐藏)