2009-12-23 7 views
10

Por común no me refiero a la utilidad, me refiero a una cabecera que contiene las enumeraciones que varios tipos quieren utilizar, etc.práctica de tener un encabezado "común"

Por ejemplo, si varios tipos pueden tener un Color , que es una enumeración, querrás que esté disponible. Algunas personas dirían que se incluya en la clase que "se adapta mejor", pero esto puede crear problemas de dependencia del encabezado.

Realmente no me gusta crear un encabezado que contenga cosas como esta, porque parece que hace que el código sea más complejo. Estoy buscando ideas de otros sobre qué técnicas emplean cuando se encuentran en una situación como esta. Si usan un encabezado "Común", etc.

Respuesta

8

Siempre uso un archivo Common.h que casi nunca cambia y contiene definiciones que muy probablemente se necesiten en prácticamente todos los archivos. Creo que aumenta la productividad para que no tenga que abrir otro archivo .cpp y copiar la lista de todos los encabezados que sabe que definitivamente necesitará.

Por ejemplo, aquí hay dos extractos de mi COMMON.H:

typedef unsigned char uint8; 
typedef signed char int8; 
typedef unsigned char uint08; 
typedef signed char int08; 
typedef unsigned short uint16; 
typedef signed short int16; 
typedef unsigned int uint32; 
typedef signed int int32; 
typedef unsigned long long uint64; 
typedef signed long long int64; 
typedef const char cchar; 
typedef const bool cbool; 
typedef char Byte; 


#ifdef ASSERT 
/* Re-defining assert */ 
#undef ASSERT 
#endif 

#ifdef DEBUG 
#ifndef ASSERTIONS 
#define ASSERTIONS 
#endif 
#endif 

#define ASSERT_ALWAYS(Expression) if (!(Expression)) FatalError(ErrorInfo("Assertion Failure", #Expression, FUNCTION_NAME, __FILE__, __LINE__)) 

#ifdef ASSERTIONS 
#ifdef DEBUG 
#define ASSERT(Expression) ASSERT_ALWAYS(Expression) 
#else 
#define ASSERT(Expression) if (!(Expression)) ErrorLog("[Release Assertions]: The following assertion failed: " # Expression) 
#endif 
#else 
#define ASSERT(Expression) 
#endif 
+0

Empecé a usar y sus tipos de estándares ISO/IEC 9899 (a veces llamados tipos C99), p. uint32_t. – paxos1977

+3

Sí, o (según su plataforma, política de código de terceros) son mucho mejores que tratar de usar sus propios typedefs. – Tom

5

El encabezado común está bien siempre y cuando haya pocas personas trabajando en su proyecto. Una vez que tienes más de 20 personas editando ese archivo y fusionando los cambios hacia adelante y hacia atrás, comienzas a tener una pesadilla.

Quizás una alternativa sería tener un archivo color.h o common/color.h, lo que impondría cierta estructura en sus archivos.

+0

Lo he considerado, pero tener un archivo de encabezado con una enumeración parece ... incorrecto. – Anonymous

+3

¿Por qué? Mantiene sus datos separados y es fácil de ver y modificar. – GManNickG

+1

(+1) Para el consejo de sonido, si va a haber varias personas que interfieren con el único archivo común (es decir, si es un archivo caliente) intente dividirlo en fragmentos relativamente más fríos ... siempre puede concatenarlos como un paso de compilación. Dicha separación en archivos más fríos también ayudará en el control de su versión. –

2

cabeceras OMI comunes son las buenas prácticas si se les restringe a que contiene cosas que rara vez cambian como

typedef unsigned int UINT32; 

Si te encuentras editando mucho este archivo, entonces tienes cosas que no pertenecen allí.

4

Personalmente no soy fan.

  1. I significa que cuando se modifica una constante (o tipo) que se utiliza en un solo lugar, es necesario volver a compilar todo el proyecto.
  2. El valor de la constante (o definición del tipo) y el uso de dicha constante (o tipo) se encuentran en dos lugares diferentes.

En general, me gusta definir una constante que se usa sólo una vez, al lado de donde se utiliza. Esto significa que si quiero saber qué valor tiene la constante, está ahí para que la mire. También significa que solo necesito recompilar un archivo cuando dicha constante cambia.

Existe un caso para un archivo de encabezado constante si la constante o el tipo se usa extensamente o si una constante o tipo se comparte entre los módulos.

1

Si desea enum 'globales', colóquelas en su propio espacio de nombres en lugar de contaminar el espacio de nombres global, p.:

// Types.h 

namespace MyTypes 
{ 
    enum Color 
    { 
     RED, 
     BLUE, 
     GREEN, 
    }; 
} 

Personalmente prefiero mantener las enumeraciones asociadas con una clase pero YMMV.

2

Prefiero ser explícito sobre lo que necesita cada uno de los archivos cpp. Encuentro que es más fácil a largo plazo y evita que los encabezados 'comunes' provoquen la reconstrucción de los archivos cuando no es necesario. A medida que crece el proyecto, tener una política estricta de "incluir solo lo que necesita" puede ayudar a mantener bajos los tiempos de construcción. El precio de esto es un poco pensado cuando inicialmente estás construyendo una nueva clase. A menudo tengo archivos de encabezado solo para una sola enumeración o tipodef e incluso llego a tener una configuración de compilación especial que compila sin encabezados precompilados y (dado que trabajo con Visual Studio) uso #pragma hdrstop para definir mis encabezados precompilados en lugar de tener todos los archivos necesita incluir un archivo común para este propósito.

A lo largo de los años he encontrado que esto funciona muy bien para mantener los tiempos de compilación reducidos y permitir que el código se mueva (en bibliotecas o en otros proyectos) o construido para arneses de prueba.

Veo los encabezados comunes como un acoplamiento innecesario que debe eliminarse y, para ser honesto, un signo de flojera y falta de atención al detalle.

Cuestiones relacionadas