¿Por qué ocurre esto si tengo los protectores en su lugar? Pensé que impedían que se leyera el encabezado después del primer acceso.
Incluir guardias aseguran que una cabecera se incluye sólo una vez en un archivo (unidad de traducción). Para varios archivos, incluido el encabezado, desea que el encabezado se incluya en cada archivo.
Por definir, en contraposición a declarar variables con vinculación externa (variables globales) en el archivo de cabecera, sólo se puede incluir en la cabecera del archivo de origen de una vez. Si incluye el encabezado en múltiples archivos fuente, habrá múltiples definiciones de una variable, lo cual no está permitido en C++.
Por lo tanto, como ha descubierto, no es una buena idea definir variables en un archivo de encabezado precisamente por el motivo anterior.
¿Por qué las numerosas enumeraciones en este encabezado no dan también las advertencias LNK4006?
Porque no definen "variables globales", son solo declaraciones sobre tipos, etc. No reservan ningún almacenamiento.
Si agrego estática antes de la firma, no aparece la advertencia. ¿Cuáles son las implicaciones de hacerlo de esta manera?
Cuando realiza una variable static
, que tiene alcance estática. El objeto no es visible fuera de la unidad de traducción (archivo) en la que está definido. Por lo tanto, en términos simples, si usted tiene:
static int i;
en su encabezado, cada archivo de origen en el que se incluirá la cabecera tendrá un separadaint
variable de i
, que está fuera invisible del archivo de origen. Esto se conoce como enlace interno.
Hay una manera mejor de hacer esto que evita el error, pero me permite declarar la matriz en el encabezado. Realmente odiaría tener un archivo cpp solo para una definición de matriz.
Si desea que la matriz sea un objeto visible desde todos los archivos de C++, que debe hacer:
extern int array[SIZE];
en el archivo de cabecera, y luego incluir el archivo de cabecera en todos los archivos de código fuente en C++ que necesitan la variable array
. En uno de los (.cpp
) archivos de origen, es necesario definir array
:
int array[SIZE];
debe incluir la cabecera en el archivo fuente anterior, así, para permitir la captura de errores debido a una diferencia en la cabecera y el archivo fuente.
Básicamente, extern
le dice al compilador que "array
se define en alguna parte, y tiene el tipo int
, y el tamaño SIZE
". Entonces, realmente definearray
una sola vez. En la etapa de enlace, todo se resuelve muy bien.
el enlazador solo está traduciendo la sintaxis de la matriz a la sintaxis del puntero. No es un error, es solo una advertencia, el programa se ejecuta como se esperaba. – Steve