2009-12-13 16 views
53

Escribí el siguiente código para explicar mi problema. Si comento la línea 11 (con la palabra clave "using"), el compilador no compila el archivo y muestra este error: invalid conversion from 'char' to 'const char*'. Parece que no se ve el método void action(char) de la clase Parent en la clase Son.¿Por qué debería usar la palabra clave "using" para acceder a mi método de clase base?

¿Por qué el compilador se comporta de esta manera? ¿O he hecho algo mal?

class Parent 
{ 
    public: 
     virtual void action(const char how){ this->action(&how); } 
     virtual void action(const char * how) = 0; 
}; 

class Son : public Parent 
{ 
    public: 
     using Parent::action; // Why should i write this line? 
     void action(const char * how){ printf("Action: %c\n", *how); } 
}; 

int main(int argc, char** argv) 
{ 
    Son s = Son(); 
    s.action('a'); 
    return 0; 
} 
+0

Por favor, dime: ¿y si eliminas const en "const char how"? –

+24

No necesita escribir 'Son s = Son();'. Eso solo crea un temporal y luego llama al constructor de copia. Simplemente escriba 'Son s;' –

+3

Tenemos esta pregunta MUCHO: [http://stackoverflow.com/questions/1835988](http://stackoverflow.com/questions/1835988) [http://stackoverflow.com/ preguntas/411103] (http://stackoverflow.com/questions/411103) [http://stackoverflow.com/questions/1480085](http://stackoverflow.com/questions/1480085) [http: // stackoverflow. com/questions/1799497] (http://stackoverflow.com/questions/1799497) [http://stackoverflow.com/questions/888235](http://stackoverflow.com/questions/888235) [http: // stackoverflow.com/questions/72010](http://stackoverflow.com/questions/72010) –

Respuesta

47

El action declarado en la clase derivada oculta la action declarado en la clase base. Si usa action en un objeto Son, el compilador buscará en los métodos declarados en Son, busque uno llamado action y úselo. No continuará la búsqueda en los métodos de la clase base, ya que ya encontró un nombre coincidente.

Entonces, ese método no coincide con los parámetros de la llamada y se obtiene un error.

Consulte también C++ FAQ para obtener más explicaciones sobre este tema.

+8

@sth Es bueno saber eso. ¿Pero es esto, puedo decir, una característica de C++ o algún tipo de error? ¿Esto no arruina toda la idea de la herencia? solo preguntando ... – Anubis

+0

¿Se hace la coincidencia de nombres usando el nombre destrozado, la sobrecarga de métodos juega un papel aquí, o se llama a la primera función que tiene el nombre de "acción" y eso es todo? – tmaric

+3

@Anubis: la regla simplifica la búsqueda de nombres. Sin él, el compilador tendría que recorrer el árbol de herencia completo cuando necesita resolver el nombre de una función miembro (podría haber sobrecargas de la función en alguna clase base).Con la regla, el compilador puede dejar de mirar el resto del árbol de herencia una vez que encontró una clase que contiene un nombre apropiado. El programador está en la misma situación. Al observar la clase derivada, puede estar seguro de que se llamará a la función definida allí, sin tener que saber si alguna clase base podría contener una función diferente del mismo nombre. – sth

15

Sorprendentemente, este es el comportamiento estándar. Si una clase derivada declara un método con el mismo nombre que un método definido por la clase base, el método de la clase derivada 'oculta la clase base'.

Ver C++ FAQ

5

Nota de precaución: la necesidad de utilizar un "uso" en esta situación es una señal de alerta que su código puede ser confuso para otros desarrolladores (¡después de todo, confundió el compilador!). Es probable que deba cambiar el nombre de uno de los dos métodos para dejar clara la distinción a otros programadores.

Una posibilidad:

void action(const char how) 
{ 
    takeAction(&how); 
} 
void action(const char * how) 
{ 
    takeAction(how); 
} 
virtual void takeAction(const char * how) = 0; 
3

Si en una función derivada clase cualquier sobre cargado se redefine entonces toda la función sobrecargada en la clase base está oculto. Una forma de incluir ambas funcionalidades es evitar la sobrecarga de funciones en las clases. o Puede usar la palabra clave using, tal como se usa.

Cuestiones relacionadas