2011-01-19 22 views
6

Tengo una clase base que tiene dos funciones del mismo nombre pero con diferentes firmas en una herencia de dos niveles.No se puede encontrar la función de clase base si la clase base tiene dos funciones del mismo nombre

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 

} 

lo que habría esperado que mi compilador (gcc-4.3.2) para encontrar la definición correcta en (1), pero me da

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) en los otros trabajos manuales.

¿Qué necesito arreglar para que (1) funcione en general?

+1

+1 para el post bien escrito con el ejemplo completo –

Respuesta

6

Escribir using A::f dentro de la definición de C.

Usted es una víctima del nombre escondite! void C::f(int, int) oculta void A::f(int), solo porque.

3

La respuesta corta al "por qué" es "porque así es como funciona la sobrecarga". Está ocultando la sobrecarga f(int) en C. La respuesta más larga es mucho más larga.

Puede un-ocultarlo al hacer esto:

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

Puede decirnos cuanto más tiempo responder? –

+0

@honk: No en este momento, tengo poco tiempo. Pero pediré ayuda con esto. –

+2

No es largo, pero aquí hay una explicación: http://stackoverflow.com/questions/888235/overriding-a-bases-overloaded-function-in-c/888337#888337 –

4

Las reglas de búsqueda de nombres C++ lo tienen de modo que si un nombre se redefine en un ámbito, todas las sobrecargas de ese nombre están ocultas.

Pero puede usar using para ayudar. De esta manera:

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; 
} 

de salida es:

A::f 2 
Cuestiones relacionadas