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
的所有变体都纳入了派生的类的范围。这个答案比我的答案更好,而且可能是应该接受的答案。