可能的重复:
名称隐藏和脆弱的基础问题
我熟悉涉及成员函数隐藏的规则。基本上,具有与基类函数同名的函数的派生类实际上不会重载基类函数 - 它完全隐藏了它。
struct Base
{
void foo(int x) const
{
}
};
struct Derived : public Base
{
void foo(const std::string& s) { }
};
int main()
{
Derived d;
d.foo("abc");
d.foo(123); // Will not compile! Base::foo is hidden!
}
所以,你可以通过以下方式解决这个问题using
宣言。但我的问题是,基类函数隐藏的原因是什么?这是标准委员会的一个“功能”还是一个“错误”?是否存在某些技术原因导致编译器在找不到匹配项时无法在基类中查找匹配重载d.foo(123)
?
名称查找的工作原理是在当前范围中查找匹配的名称,如果没有找到任何内容,则在封闭范围中查找,如果没有找到,则在封闭范围中查找,依此类推,直到到达全局命名空间。
这不是特定于类的,您可以在这里得到完全相同的名称:
#include <iostream>
namespace outer
{
void foo(char c) { std::cout << "outer\n"; }
namespace inner
{
void foo(int i) { std::cout << "inner\n"; }
void bar() { foo('c'); }
}
}
int main()
{
outer::inner::bar();
}
虽然outer::foo(char)
更适合通话foo('c')
找到后停止名称查找outer::inner::foo(int)
(i.e. outer::foo(char)
被隐藏),所以程序打印inner
.
如果不隐藏成员函数名称,则意味着类作用域中的名称查找行为与非类作用域不同,这会不一致且令人困惑,并使 C++ 更难学习。
因此,没有技术原因无法更改名称查找规则,但必须针对成员函数和其他类型的名称查找更改它们,这会使编译器变慢,因为即使在之后,它们也必须继续搜索名称在当前范围内查找匹配的名称。显然,如果当前范围内有一个名称,那么它就是probably你想要的那个。范围内的调用A
可能想在该范围内查找名称,例如如果两个函数位于同一名称空间中,它们可能是相关的(同一模块或库的一部分),因此如果一个函数使用另一个函数的名称,则可能意味着在同一范围内调用另一个函数。如果这不是您想要的,则使用显式限定或 using 声明来告诉编译器其他名称应该在该范围内可见。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)