Si declaro una clase base (o clase de interfaz) y especifico un valor predeterminado para uno o más de sus parámetros, ¿las clases derivadas tienen que especificar los mismos valores predeterminados y, de no ser así, qué valores predeterminados se manifestarán en las clases derivadas?
Anexo: También estoy interesado en cómo se puede manejar esto en los diferentes compiladores y cualquier aportación sobre la práctica "recomendada" en este escenario.
Respuestas:
Los virtuales pueden tener valores predeterminados. Los valores predeterminados en la clase base no son heredados por las clases derivadas.
El valor predeterminado que se usa, es decir, la clase base 'o una clase derivada', está determinado por el tipo estático utilizado para realizar la llamada a la función. Si llama a través de un objeto de clase base, puntero o referencia, se utiliza el valor predeterminado indicado en la clase base. Por el contrario, si llama a través de un objeto de clase derivada, puntero o referencia, se utilizan los valores predeterminados indicados en la clase derivada. Hay un ejemplo debajo de la cita estándar que lo demuestra.
Algunos compiladores pueden hacer algo diferente, pero esto es lo que dicen los estándares C ++ 03 y C ++ 11:
Aquí hay un programa de muestra para demostrar qué valores predeterminados se seleccionan. Estoy usando
struct
s aquí en lugar declass
es simplemente por brevedad,class
ystruct
son exactamente iguales en casi todos los aspectos, excepto en la visibilidad predeterminada.La salida de este programa (en MSVC10 y GCC 4.4) es:
fuente
Este fue el tema de uno de los primeros gurús de la semana de Herb Sutter publicaciones .
Lo primero que dice sobre el tema es NO HAGAS ESO.
Con más detalle, sí, puede especificar diferentes parámetros predeterminados. No funcionarán de la misma manera que las funciones virtuales. Se llama a una función virtual en el tipo dinámico del objeto, mientras que los valores de los parámetros predeterminados se basan en el tipo estático.
Dado
deberías obtener A :: foo1 B :: foo2 B :: foo1
fuente
Esta es una mala idea, porque los argumentos predeterminados que obtendrá dependerán del tipo estático del objeto, mientras que la
virtual
función enviada dependerá del tipo dinámico .Es decir, cuando llama a una función con argumentos predeterminados, los argumentos predeterminados se sustituyen en tiempo de compilación, independientemente de si la función es
virtual
o no.@cppcoder ofreció el siguiente ejemplo en su pregunta [cerrada] :
Lo que produce el siguiente resultado:
Con la ayuda de la explicación anterior, es fácil ver por qué. En tiempo de compilación, el compilador sustituye los argumentos predeterminados de las funciones miembro de los tipos estáticos de los punteros, haciendo que la
main
función sea equivalente a lo siguiente:fuente
Como puede ver en las otras respuestas, este es un tema complicado. En lugar de intentar hacer esto o entender lo que hace (si tiene que preguntar ahora, el responsable tendrá que preguntar o buscarlo dentro de un año).
En su lugar, cree una función pública no virtual en la clase base con parámetros predeterminados. Luego llama a una función virtual privada o protegida que no tiene parámetros predeterminados y se anula en las clases secundarias según sea necesario. Entonces no tiene que preocuparse por los detalles de cómo funcionaría y el código es muy obvio.
fuente
Este es uno que probablemente pueda resolver razonablemente bien mediante la prueba (es decir, es una parte del lenguaje lo suficientemente convencional como para que la mayoría de los compiladores lo entiendan correctamente y, a menos que vea diferencias entre los compiladores, su salida puede considerarse bastante autorizada)
fuente
Como han detallado otras respuestas, es una mala idea. Sin embargo, como nadie menciona una solución simple y efectiva, aquí está: ¡Convierta sus parámetros en estructura y luego puede tener valores predeterminados para miembros de estructura!
Entonces, en lugar de
hacer esto,
fuente