¿Qué debería y qué no debería estar en un archivo de encabezado? [cerrado]

56

¿Qué cosas nunca deberían incluirse en un archivo de encabezado?

Si, por ejemplo, estoy trabajando con un formato estándar documentado de la industria que tiene muchas constantes, ¿es una buena práctica definirlas en un archivo de encabezado (si estoy escribiendo un analizador para ese formato)?

¿Qué funciones deben ir en el archivo de encabezado?
¿Qué funciones no deberían?

    
pregunta Moshe Magnes 06.10.2012 - 10:13

5 respuestas

45

Qué poner en los encabezados:

  • El conjunto mínimo de directivas #include que se necesitan para que el encabezado sea compilable cuando el encabezado se incluye en algún archivo fuente.
  • Definiciones de símbolos del preprocesador de cosas que deben compartirse y que solo se pueden lograr a través del preprocesador. Incluso en C, los símbolos del preprocesador se mantienen mejor al mínimo.
  • Declaraciones directas de las estructuras que son necesarias para que las definiciones de estructura, los prototipos de funciones y las declaraciones de variables globales en el cuerpo del encabezado sean compilables.
  • Definiciones de estructuras de datos y enumeraciones que se comparten entre varios archivos de origen.
  • Declaraciones de funciones y variables cuyas definiciones serán visibles para el vinculador.
  • Definiciones de funciones en línea, pero tenga cuidado aquí.

Lo que no pertenece a un encabezado:

  • Directivas gratuitas #include . Aquellos gratuitos incluyen la causa de la compilación de cosas que no necesitan ser compiladas, y en ocasiones pueden hacerlo para que un sistema no pueda compilar. No #include un archivo en un encabezado si el encabezado en sí no necesita ese otro archivo de encabezado.
  • Símbolos del preprocesador cuya intención podría lograrse mediante algún mecanismo, cualquier otro mecanismo, que no sea el preprocesador.
  • Lotes y muchas definiciones de estructuras. Divídalos en encabezados separados.
  • Definiciones en línea de funciones que requieren un #include adicional, que están sujetos a cambios o que son demasiado grandes. Esas funciones en línea deberían tener poco o ningún abanico, y si tienen abanico, deberían estar localizadas para las cosas definidas en el encabezado.

¿Qué constituye el conjunto mínimo de #include enunciados?

Esto resulta ser una pregunta no trivial. Una definición de TL; DR: Un archivo de encabezado debe incluir los archivos de encabezado que definen directamente cada uno de los tipos utilizados directamente o que declaran directamente cada una de las funciones utilizadas en el archivo de encabezado en cuestión, pero no deben incluir nada más. Un puntero o un tipo de referencia de C ++ no califican como uso directo; se prefieren las referencias hacia adelante.

Hay un lugar para una directiva #include gratuita, y esto está en una prueba automatizada. Para cada archivo de encabezado en un paquete de software, genero automáticamente y luego compilo lo siguiente:

#include "path/to/random/header_under_test"
int main () { return 0; }

La compilación debe estar limpia (es decir, libre de advertencias o errores). Las advertencias o errores con respecto a tipos incompletos o tipos desconocidos significan que el archivo de encabezado bajo prueba tiene algunas directivas #include faltantes y / o declaraciones adelantadas faltantes. Tenga en cuenta que: el hecho de que la prueba se apruebe no significa que el conjunto de directivas #include sea suficiente, y mucho menos mínimo.

    
respondido por el David Hammen 06.10.2012 - 16:39
13

Además de lo que ya se ha dicho.

Los archivos H siempre deben contener:

  • Documentación del código fuente !!! Como mínimo, cuál es el propósito de los diversos parámetros y valores de retorno de las funciones.
  • Guardias de encabezado, #ifndef MYHEADER_H #define MYHEADER_H ... #endif

Los archivos H nunca deben contener:

  • Cualquier forma de asignación de datos.
  • Definiciones de funciones. Las funciones en línea pueden ser una rara excepción en algunos casos.
  • Cualquier cosa etiquetada como static .
  • Typedefs, #defines o constantes que no tienen relevancia para el resto de la aplicación.

(También diría que nunca hay ninguna razón para usar variables externas / externas no constantes, en cualquier lugar, pero eso es una discusión para otra publicación).

    
respondido por el user29079 08.10.2012 - 15:08
4

Probablemente nunca diría nunca, pero las declaraciones que generan datos y códigos a medida que se analizan no deberían estar en un archivo .h.

Las macros, las funciones en línea y las plantillas pueden parecerse a datos o código, pero no generan código cuando se analizan, sino cuando se usan. Estos elementos a menudo deben usarse en más de un .c o .cpp, por lo que pertenecen a .h.

En mi opinión, un archivo de encabezado debe tener la interfaz práctica mínima para un .c o .cpp correspondiente. La interfaz puede incluir #defines, clase, typedef, definiciones de estructura, prototipos de funciones y definiciones externas menos preferidas para variables globales. Sin embargo, si una declaración se usa en un solo archivo de origen, probablemente debería excluirse de la .h y estar contenida en el archivo de origen.

Algunos pueden estar en desacuerdo, pero mi criterio personal para los archivos .h es que #incluyen todos los demás archivos .h que necesitan para poder compilar. En algunos casos, esto puede ser una gran cantidad de archivos, por lo que contamos con algunos métodos efectivos para reducir las dependencias externas, como las declaraciones de reenvío a clases, que nos permiten usar punteros a objetos de una clase sin incluir lo que podría ser un gran árbol de archivos de inclusión. / p>     

respondido por el DeveloperDon 06.10.2012 - 22:14
3

El archivo de encabezado debe tener la siguiente organización:

  • definiciones de tipo y constantes
  • declaraciones de objetos externos
  • declaraciones de funciones externas

Los archivos de encabezado nunca deben contener definiciones de objeto, solo definiciones de tipo y declaraciones de objeto.

    
respondido por el theD 06.10.2012 - 11:40
0

Las declaraciones que generan datos y código a medida que se analizan, no deben estar en un archivo .h . En lo que respecta a mi punto de vista, un archivo de encabezado solo debe tener la interfaz práctica mínima para un correspondiente .c o .cpp .

    
respondido por el Ajay Prasad 01.03.2014 - 17:08

Lea otras preguntas en las etiquetas