Tengo una tarea asignada y necesito evaluar qué enfoque es mejor de acuerdo con GRASP "Variación protegida". Encontré una pregunta en Stack Overflow sobre la separación de los archivos de encabezado y código en C ++ .
Sin embargo, lo que quiero saber es por qué Java no sigue a C ++ al promover la separación entre las definiciones de clase y las implementaciones de clase. ¿Hay alguna ventaja con el método Java, sobre el método C ++?
java
programming-languages
c++
Etienne Noël
fuente
fuente
private
así, para que la implementación conozca el tamaño y lasprivate
funciones de los miembros también.Respuestas:
¿Cuántas líneas de código hay en el siguiente programa?
Probablemente respondió 7 (o 6 si no contó la línea en blanco, o 4 si no contó las llaves).
Sin embargo, su compilador ve algo muy diferente:
Sí, eso es 18.7 KLOC solo por un "¡Hola, mundo!" programa. El compilador de C ++ tiene que analizar todo eso. Esta es una razón importante por la que la compilación de C ++ tarda tanto en comparación con otros lenguajes, y por qué los lenguajes modernos evitan los archivos de encabezado.
Una mejor pregunta sería
¿ Por qué C ++ tiene archivos de encabezado?
C ++ fue diseñado para ser un superconjunto de C, por lo que tenía que mantener los archivos de encabezado para la compatibilidad con versiones anteriores.
Bien, entonces ¿por qué C tiene archivos de encabezado?
Debido a su primitivo modelo de compilación por separado. Los archivos de objetos generados por los compiladores de C no incluyen ningún tipo de información, por lo que para evitar errores de tipo, debe incluir esta información en su código fuente.
Agregar las declaraciones de tipo adecuadas corrige el error:
Tenga en cuenta que no hay
#include
s. Pero cuando usa una gran cantidad de funciones externas (que la mayoría de los programas usarán), declararlas manualmente se vuelve tedioso y propenso a errores. Es mucho más fácil usar archivos de encabezado.¿Cómo pueden los idiomas modernos evitar los archivos de encabezado?
Mediante el uso de un formato de archivo de objeto diferente que incluye información de tipo. Por ejemplo, el formato de archivo Java * .class incluye "descriptores" que especifican los tipos de campos y parámetros de métodos.
Este no fue un invento nuevo. Anteriormente (1987), cuando Borland agregó "unidades" compiladas por separado a Turbo Pascal 4.0, eligió usar un nuevo
*.TPU
formato en lugar de Turbo C*.OBJ
para eliminar la necesidad de archivos de encabezado.fuente
OBJ
los archivos en lugar deTPU
s ...Java tiene interfaces para definir un contrato. Esto proporciona un mayor nivel de abstracción de lo que necesita la persona que llama y la implementación real. es decir, la persona que llama no necesita conocer la clase de implementación, solo necesita conocer el contrato que admite.
Supongamos que desea escribir un método que ralentice todas las claves / valores en un Mapa.
Este método puede llamar a entrySet () en una interfaz abstracta que se elimina de la clase que lo implementa. Puedes llamar a este método con.
fuente
#define interface class
.virtual
palabra clave para obtener polimorfismo y esto no tiene penalización de rendimiento si solo usa uno o dos tipos concretos, como en Java. ¿Me puede indicar alguna documentación sobre cómo funciona esto en C ++?Los encabezados existen, francamente, como un accidente histórico. Es un sistema increíblemente pobre, ningún otro idioma tiene algo tan terrible, y cualquiera que no tenga que lidiar con ellos debería alegrarse.
fuente
Los encabezados están ahí para permitir una compilación separada. Al incluir los encabezados, el compilador no necesita saber nada sobre la estructura binaria del código C ++ compilado, y puede dejar ese trabajo en un vinculador separado. Java no utiliza un vinculador separado con su compilador, y dado que los archivos .class están estrictamente definidos, el compilador puede leerlos para determinar todos sus miembros con todos sus tipos, sin necesidad de volver a declararlos en cada unidad de compilación.
Puede incluir toda la implementación en un encabezado C ++, pero hace que el compilador lo vuelva a compilar cada vez que está #incluido, lo que obliga al vinculador a ordenar y descartar las copias duplicadas.
fuente
Java promueve la separación de la definición de clase y la implementación, solo depende de dónde se mire.
Cuando eres el autor de una clase Java, puedes ver la definición de la clase y su implementación en un solo archivo. Esto simplifica el proceso de desarrollo, ya que solo tiene que ir a un lugar para mantener la clase, no tiene que cambiar entre dos archivos (.h y .cpp como lo haría en C ++). Sin embargo, cuando eres el consumidor de la clase solo tratas con la definición, a través de un archivo .class que está empaquetado en un .jar o un .class independiente.
C ++ le permite separar la definición y la implementación, pero es ad-hoc. Por ejemplo, no hay nada que le impida escribir el método en línea dentro del archivo de encabezado, y para las clases de plantilla esto es obligatorio. El archivo de encabezado también enumera las variables miembro, que son visibles para cualquiera que mire el archivo de encabezado, aunque sean detalles de implementación de la clase e irrelevantes para un consumidor.
fuente