C++ 函数不';t参与继承中的重载解析

C++ 函数不';t参与继承中的重载解析,c++,oop,c++11,inheritance,polymorphism,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

考虑以下示例:

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
的定义会导致编译成功

这是由于方法隐藏造成的,即使签名不同。正如一些程序员所提到的,“如果您为已经存在于基类中的子类中的成员使用符号,则基类中的符号是隐藏的”


请阅读

中的更多内容,过载不会通过不同的作用域发生

对于
fun(42.42f),必须找到名称
fun
。根据以下规则:

对于非限定名称,即不出现在作用域解析运算符右侧的名称::,名称查找将按如下所述检查作用域,直到找到至少一个任何类型的声明,此时查找停止,不再检查其他作用域

这意味着该名称将在类
Derived
的范围内找到,即
Derived::fun()
。然后停止名称查找,将根本不考虑
Base
范围内的名称

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


<> P>查找之后发生的事情也是值得注意的。

这对我来说似乎不合逻辑,因为隐藏的方法有不同的签名。@ DeIDi不管你认为它是多么“不合逻辑”,C++是如何工作和设计的。如果在基类中已经存在的子类中为成员使用符号,则基类中的符号将被隐藏。@DeiDei-answer已更新,希望现在有所帮助!某个程序员是对的,他把这句话注入了我的答案中!=)@DeiDei它避免了问题。解决问题的另一种方法是使用Base::fun派生类中的code>。这就把
Base::fun
的所有变体都纳入了
派生的
类的范围。这个答案比我的答案更好,而且可能是应该接受的答案。