如果baseclass有两个同名函数,则找不到baseclass函数

时间:2011-01-19 23:07:41

标签: c++ inheritance

我有一个基类,它有两个同名的函数,但在2级继承中有不同的签名。

struct A {
    virtual void f(int) { }
    virtual void f(int, int) { };
    virtual void f1(int) { }
};

struct B: public A { };

struct C: public B {
  void f(int, int) { }
  void f1(int) { }
};

int main() {
 C obj;
 obj.f1(0);
 obj.f(0,0);

 obj.f(0);    // (1) cannot be found
 obj.B::f(0); // (2) works

}

我原本希望我的编译器(gcc-4.3.2)能够在(1)找到正确的定义,但我得到了

g++     main.cpp   -o main
main.cpp: In function 'int main()':
main.cpp:20: error: no matching function for call to 'C::f(int)'
main.cpp:10: note: candidates are: virtual void C::f(int, int)
distcc[2200] ERROR: compile main.cpp on localhost failed
make: *** [main] Error 1
另一方面,

(2)有效。

我需要修复哪些内容才能使(1)正常工作?

3 个答案:

答案 0 :(得分:6)

using A::f写在C的定义中。

你是名字隐藏的受害者! void C::f(int, int)隐藏了void A::f(int),只是因为。

答案 1 :(得分:5)

C ++名称查找规则使得如果在一个范围内重新定义名称,则隐藏该名称的所有重载。

但您可以使用using来提供帮助。像这样:

class A {
    public:
    int f(int x) { cout << "A::f 1\n"; }
    int f(int x, int y) { cout << "A::f 2\n"; }
};

class B : public A {
    public:
    using A::f;
    int f(int x) { cout << "B::f 1\n"; }
};

int main()
{
    B b;

    b.f(27, 34);

    return 0;
}

输出是:

A::f 2

答案 2 :(得分:3)

对“为什么”的简短回答是“因为这就是超载的工作方式。”您在C中隐藏f(int)重载。答案越长,答案就越长。

您可以通过执行以下操作取消隐藏它:

struct C: public B {
  using A::f;
  void f(int, int) { }
  void f1(int) { }
};