函数不参与继承中的重载解析

时间:2017-06-18 13:49:56

标签: c++ oop c++11 inheritance polymorphism

考虑以下示例:

struct Base
{
    virtual void fun() = 0;
    void fun(float) { fun(); }
};

struct Derived : Base
{
    void fun() override {}
    void bar()
    {
        // calling Base1::fun from, which in turn should call Derived::fun
        fun(42.42f); // error "Function does not take 1 argument"
        Base::fun(42.42f); // ok
    }
};

为什么在这种情况下需要指定fun的范围?不应该隐含地考虑基类fun吗?

为什么删除Derived::fun的定义会导致编译成功?

2 个答案:

答案 0 :(得分:3)

不会通过不同的范围进行重载。

对于fun(42.42f);,必须找到名称fun。根据{{​​3}}的规则:

  

对于非限定名称,即不在范围解析运算符::右侧显示的名称,名称查找检查范围如下所述,直到它找到至少一个任何类型的声明,此时查找停止,不再检查其他范围。

这意味着名称将在班级Derived的范围内找到,即Derived::fun()。然后名称查找停止,Base范围内的名称将完全不被考虑。

如果删除Derived::fun的定义,则Derived的范围内不会找到任何名称,那么将进一步检查基类的范围(即Base)并且会找到Base::foo。一切正常。

值得注意的是unqualified name lookup在名字查找后发生。

答案 1 :(得分:2)

这是因为 Method Hiding 引起的,即使签名有所不同也很难。正如一些程序员提到的那样“如果你在一个已经存在于基类中的子类中使用一个成员的符号,那么基类中的符号就会被隐藏”。

请在Why does an overridden function in the derived class hide other overloads of the base class?

中阅读更多内容