void f()
{}
struct A
{
void f()
{}
};
struct B : A
{
B()
{
f(); // A::f() is always called, and ::f is always ignored
}
};
int main()
{
B();
}
作为班级B
的设计师,我可能不知道B
的基类,即A
,有一个成员函数A::f
,我只知道::f
,然后致电::f
就是我想要的。
我期望编译器因为调用f
的模糊性而给出错误。但是,编译器始终选择A::f
并忽略::f
。我认为这可能是一个很大的陷阱。
我只是想知道:
为什么成员函数的重载解析会排除全局函数?
理由是什么?
答案 0 :(得分:4)
作为B级设计师,我可能不知道B的基础
我不同意。
为什么成员函数的重载解析不包括 全球职能?
因为两个重载属于两个不同的范围,编译器选择相同范围的重载。阅读§3.4.1。内部(相同)范围的f
隐藏了外部的f
。
理由是什么?
要有一个可靠的规则。我们更喜欢在同一范围内工作。除非我们明确想要从其他地方调用一个对象。
在一个家庭中打电话给Alex,他们希望他们的小男孩Alex进来,而不是Alexander III of Macedon。
答案 1 :(得分:3)
这就是重载解析的工作原理,很好。
想象一下,你真的有一个大项目,大量的相互依赖,第三方代码和跨模块包括。在这个巨大的混乱中,你有一个你认识的课程。它已经工作了5年,它高效,易于阅读和清洁。你不想碰它。然后升级模块,开始收到编译器错误。不好了!该模块(您无法控制)在全局命名空间中引入了新函数DoAmazingStuff()
。与我们班级中的方法名称相同。您将不得不重构它,因为现在您不能再为类成员使用相同的名称。无赖!