为什么必须使用继承类的全名来调用具有相同名称(不是签名)的基类的方法?

时间:2015-11-29 16:44:29

标签: c++ inheritance

这是一个理论问题,只是为了更好地理解为什么不支持以下场景。

查看以下代码:

class A
{
public:
    A(){}

    void f(int x){ printf("A::f(x)\r\n"); }
    void g(int x){ printf("A::g(x)\r\n"); }
};

class B : public A
{
public:
    B(){}

    void f(){ f(5); } // <- does not compile
    void f(){ A::f(5); } // <- compiles
    void f(){ g(5); } // <- compiles
};

B类继承A类。

当B :: f()通过不使用其全名调用A :: f()时(即void f(){f(5);}),B :: f()无法编译,因为它不能找到函数A :: f(int)。 问题是为什么?

使用全名(显然有助于... void f(){A :: f(5);})。但真正令人感到奇怪的是void f(){g(5);工作!

我明白这是因为f()是在A和B中实现的,但为什么编译器不能自己理解该方法是在A类?

谢谢!

P.S。我的猜测是可能f()不仅在A中实现,而且可能在A的基类中实现,所以在这样的情况下编译器不能真正知道,但是就像我一样写道,我只是在猜...

1 个答案:

答案 0 :(得分:1)

编译器首先按名称查找函数,忽略参数。所以它看到B::f()然后开始尝试匹配参数。由于B::f()不带参数,编译器会抛出错误。通过调用g()B中没有匹配项,因此编译器会查找A并找到它。