为什么下面的表达式 'd.f(1);' 在 main() 中没有歧义?

Why there's no ambiguity in the expression `d.f(1);` below in main()?

本文关键字:main 歧义 表达式 为什么      更新时间:2023-10-16

为什么Base::f(int)Derived::f(int)之间的main()中下面的表达式d.f(1);没有歧义?

class Base
{
    public:
    void f(int i) {}
    void f(int i, int j) {}
};
class Derived : public Base
{
    public:
    using Base::f;
    void f(int i) {}
};
int main()
{
    Derived d;
    d.f(1);
}

正如其他人所写,由于Derived::f(int)隐藏了Base::f(int),因此不存在歧义。您可能期望只有在没有using声明的情况下才会出现这种情况:

using Base::f;

但隐藏仍然适用。C++11标准第7.3.3/15段规定:

using声明将基类的名称带入派生类作用域时,成员函数和派生类中的成员函数模板覆盖和/或隐藏成员函数和成员函数具有相同名称的模板、参数类型列表(8.3.5)、cv限定符ref限定符(如果有)基类(而不是冲突的)

它还提供了一个与您的示例非常相似的示例(请查看表达式p->f(1)如何不会导致歧义,而是选择D::f):

struct B {
    virtual void f(int);
    virtual void f(char);
    void g(int);
    void h(int);
};
struct D : B {
    using B::f;
    void f(int); // OK: D::f(int) overrides B::f(int);
    using B::g;
    void g(char); // OK
    using B::h;
    void h(int); // OK: D::h(int) hides B::h(int)
};
void k(D* p)
{
    p->f(1); // calls D::f(int)
    p->f(’a’); // calls B::f(char)
    p->g(1); // calls B::g(int)
    p->g(’a’); // calls D::g(char)
}

派生类中的函数隐藏基类中的函数
这叫做阴影。

因为d的静态类型是Derived,而Derived::f(int)隐藏Base::f(int)