2011-12-29 7 views
5

No veo por qué la declaración de void operator()(int) en la clase base en el siguiente ejemplo de código está aparentemente oculta cuando la clase derivada implementa void operator()(int,int,int). ¿Cómo puedo obtener la declaración de operator() (int) de la clase base foo para ser visible en la clase derivada bar? Es decir, ¿cómo puedo modificar el ejemplo para que funcione la invocación de operator() (int)?Herencia del operador()

#include <iostream> 

struct foo 
{ 
     void operator()(int) 
     { 
       std::cout << "A" << std::endl; 
     } 
}; 

struct bar : foo 
{ 
     // If this is uncommented, the code will not compile. 
     // void operator()(int, int, int) {} 
}; 

int main() 
{ 
     bar b; 
     b(1); 
     return 0; 
} 

cuando se compila con g ++ con las líneas marcadas comentarios, el mensaje de error es en la línea de "no puede competir con la llamada a 'bar (int)' ... candidato es nulo bar :: operador() (int, int, int) ... el candidato espera 3 argumentos, 1 incluido ".

Respuesta

6

Correcto. Las funciones de clase derivadas ocultan funciones de clase base en lugar de sobrecargar. La solución es bastante simple:

struct bar : foo 
{ 
    using foo::operator(); 
    void operator()(int, int, int) {} 
}; 
+0

¡Gracias por la respuesta! ¿Podría explicarnos por qué la declaración de uso es necesaria en este caso? No veo cómo declarar operator() (int, int, int) debería eclipsar la declaración de operator() (int) en la clase base. Tener que especificar la palabra clave using es un poco engorroso, ya que en un escenario del mundo real, tendría que agregar esto a cada clase base. –

+4

¿Por qué? Porque el estándar así lo dice. "Un nombre puede ser ocultado por una declaración explícita de ese mismo nombre en una región declarativa anidada o clase derivada". Ver también: http://www2.research.att.com/~bs/bs_faq2.html#overloadderived –

+0

En realidad, las anulaciones de las funciones virtuales también ocultan las funciones de la clase base. Esto es especialmente molesto cuando una clase base tiene múltiples funciones virtuales públicas que son sobrecargas del mismo nombre: cuando se anula solo una de ellas, todas las demás están ocultas. Esta es una de las razones por las que la biblioteca estándar de C++ no tiene ninguna función pública virtual (a excepción de los destructores que no pueden sobrecargarse de todos modos y funcionan de alguna manera diferentes con respecto a la anulación de todos modos). En cambio, la función pública delega a las funciones virtuales protegidas (realmente deberían ser privadas). –

2

Tenga en cuenta que operator() puede hacer que esto se vea más confuso de lo que es. El ejemplo clásico probablemente sería algo más parecido a bar :: mymethod (int) y foo :: mymethod(). El método derivado oculta el método heredado por la forma en que ocurre la resolución. La declaración using explicada en otra respuesta trae el método de resolución de foo.