titulo tablas repite repetir funciona filas fila encabezados encabezado como c++ dev-c++ multiple-definition-error multiple-inclusions

c++ - tablas - Errores de definición múltiple repetidos de incluir el mismo encabezado en múltiples cpps



repetir filas de titulo en word no funciona (9)

Entonces, no importa lo que parezca, no puedo evitar que Dev C ++ arroje numerosos errores de Definición múltiple como resultado de que incluya el mismo archivo de encabezado en varios archivos de código fuente en el mismo proyecto. Preferiría evitar tener que volcar todo mi código fuente en un archivo y solo incluir el encabezado una vez, ya que eso hará que mi archivo sea muy largo y difícil de administrar.

Básicamente, esto es lo que está pasando:

#ifndef _myheader_h #define _myheader_h typedef struct MYSTRUCT{ int blah; int blah2; } MYSTRUCT; MYSTRUCT Job_Grunt; MYSTRUCT *Grunt = &Job_Grunt; MYSTRUCT Job_Uruk; MYSTRUCT *Uruk = &Job_Grunt; int Other_data[100]; void load_jobs(); #endif

Ejemplo de archivo Cpp (Casi todos se parecen a esto):

#include "myheader.h" void load_jobs(){ Grunt->blah = 1; Grunt->blah2 = 14; Uruk->blah = 2; Uruk->blah2 = 15; return; }

Tenga en cuenta que tengo alrededor de 5 archivos cpp que incluyen este encabezado, cada uno relacionado con un tipo diferente de estructura que se encuentra en el archivo de encabezado. En este ejemplo, solo había una estructura que contenía un par de miembros, cuando hay de 4 a 6 estructuras diferentes con muchos más miembros en el archivo de encabezado real. Todos los archivos que he incluido siguen la misma fórmula que se ve en este ejemplo aquí.

Ahora entiendo que el protector de encabezado solo detiene que cada archivo cpp individual incluya el archivo de encabezado más de una vez. Lo que parece estar sucediendo es que cuando el compilador lee el include al inicio de cada cpp, define el archivo de encabezado una y otra vez, lo que hace que escuche líneas y líneas de:

Multiple Definition of Uruk, first defined here Multiple Definition of Job_Uruk, first defined here Multiple Definition of Grunt, first defined here Multiple Definition of Job_Grunt, first defined here Multiple Definition of Other_data, first defined here

Veré un conjunto de esto para cada archivo cpp en el proyecto que incluye el encabezado. Intenté mover las definiciones de las variables struct y struct a los archivos cpp, pero luego los otros archivos cpp no ​​pueden verlos ni trabajar con ellos, lo cual es muy importante ya que necesito todos los archivos del proyecto para poder trabajar con estas estructuras.

Pero la parte más confusa sobre este problema requiere un poco más de explicación:

La forma en que estoy configurando estos múltiples archivos en este proyecto es idéntica al libro con el que estoy trabajando, All In One Game Programming de John S. Harbour. Me encontré con exactamente los mismos problemas cuando creé los archivos, por ejemplo, proyectos en el libro que pedían un encabezado incluido por múltiples cpps en el mismo proyecto.

Podría escribirlos, palabra por palabra del libro, y quiero decir palabra por palabra ...
y obtendría la serie de errores MD para cada cpp en el proyecto.

Si cargaba el proyecto de ejemplo desde el CD incluido con el libro, se compilaría y se ejecutaría sin problemas, aunque los archivos en sí, así como las opciones del proyecto, eran en apariencia idénticos a los que había creado.

Si creara mi propio archivo de proyecto y simplemente agregara los archivos de fuente y encabezado para el proyecto de ejemplo desde el CD, esto también se compilaría y ejecutaría, aunque no puedo encontrar ninguna diferencia entre esos y los míos.

Entonces, intenté crear mi propio archivo de proyecto, luego crear los archivos de origen y de encabezado en blanco y agregarlos y luego rellenarlos copiando y pegando sus contenidos de los archivos en el CD al que se suponía que correspondían (el mismo unos que habían funcionado). Y por supuesto, obtendría lo mismo ... líneas y líneas de mensajes de error MD.

Estoy absolutamente desconcertado. He repetido todos estos métodos varias veces, y estoy seguro de que no estoy escribiendo mal o copiando el código. Simplemente parece haber algo sobre los archivos prefabricados; alguna configuración de configuración o algo más que me falta por completo ... que hará que se compilen correctamente, mientras que los archivos que yo mismo hago no.


GCC 3.4 y superior admite #pragma once . Simplemente ponga #pragma once en la parte superior de su código en lugar de usar guardias de inclusión. Esto puede o no ser más exitoso, pero vale la pena intentarlo. Y no, esto no es (siempre) precisamente equivalente a un protector de inclusión.


Necesita definir sus variables como extern en el archivo de encabezado, y luego definirlas en un archivo cpp también. es decir:

extern MYSTRUCT Job_Grunt;

en su archivo de encabezado, y luego en un archivo cpp en su proyecto, ordénelos normalmente.

El archivo de cabecera es solo para definiciones, cuando instancia una variable en el archivo de encabezado, intentará crear una instancia cada vez que se incluya el encabezado en su proyecto. El uso de la directiva externa le dice al compilador que es solo una definición y que la instanciación se realiza en otro lugar.


Para ampliar lo que dijo Gerald, el encabezado está definiendo una instancia de la estructura (que no es lo que quieres). Esto está ocasionando que cada unidad de compilación (archivo cpp) que incluye el encabezado obtenga su propia versión de la instancia struct, lo que causa problemas en el tiempo de enlace.

Como dijo Gerald, necesitas definir una referencia a la estructura (usando ''extern'') en el encabezado, y tener un archivo cpp en tu proyecto que ejemplifique la instancia.


Si bien la mayoría de las otras respuestas son correctas en cuanto a por qué está viendo múltiples definiciones, la terminología es imprecisa. Comprender la declaración contra la definición es la clave de su problema.

Una declaración anuncia la existencia de un artículo pero no causa creación de instancias. Por lo tanto, las declaraciones externas son declaraciones, no definiciones.

Una definición crea una instancia del elemento definido. Por lo tanto, si tiene una definición en un encabezado, se crea una instancia en cada archivo .cpp, lo que da como resultado las definiciones múltiples. Las definiciones también son declaraciones, es decir, no se necesita una declaración separada si, por ejemplo, el alcance del elemento está limitado a un archivo .cpp.

Nota: el uso de la creación de instancias de palabra aquí solo se aplica a los elementos de datos.


Yo también estaba teniendo este problema hace un tiempo. Déjame intentar explicar qué lo resolvió. Tenía un archivo global.h que tenía toda la declaración y necesitaba ser incluido en cada archivo cpp. En lugar de incluirlo en cada .cpp, lo incluí en .h. Todos mis archivos ".h" He agregado las líneas #ifndef y #define y terminé con #endif. Este problema de MD resuelto. Espero que esto funcione para usted también.


Esto es lo que funcionó para mí: vincular las fuentes en bibliotecas separadas. (Mi problema no era crear un programa, sino una / muchas bibliotecas). Luego, vinculé (con éxito) un programa con las dos bibliotecas que creé.

Tenía dos conjuntos de funciones (una dependiendo de la otra) en el mismo archivo fuente y declaradas en el mismo archivo de encabezado único. Luego traté de separar los dos conjuntos de funciones en dos encabezados + archivos fuente.

Intenté con ambos #pragma una vez e incluí guardias con #ifndef ... #define ... #endif. También definí las variables y funciones como extern en los archivos de encabezado.

Como señaló Steve Fallows, el problema no está en la compilación, sino en la vinculación. En mi problema particular, podría salirse con la suya teniendo dos conjuntos de funciones, cada una en su propio archivo fuente, compilando y luego enlazando en dos bibliotecas separadas .

g++ -o grandfather.o -c grandfather.cpp g++ -o father.o -c father.cpp g++ -fPIC -shared -o libgf.so grandfather.o g++ -fPIC -shared -o libfather.so father.o

Esto me obliga a vincular mis programas con libgf.so y libfather.so. En mi caso particular, no hace diferencia; pero de lo contrario no podría hacer que trabajen juntos.


También recibí este error para una función definida en un archivo .h. El archivo de cabecera no pretendía hacer declaraciones de una clase, sino definiciones de algunas funciones que se necesitan en varios lugares de un proyecto. (Puedo confundir los usos de "definición" y "declaración", pero espero poder dar la idea principal). Cuando coloco una palabra clave "en línea" justo antes de la definición de la función que da el error "definiciones múltiples", el error es evitado


Cuando defines una variable, el compilador guarda memoria para esa variable. Al definir una variable en el archivo de encabezado e incluir ese archivo en todos sus archivos de origen, está definiendo la misma variable en varios archivos.

Situar la palabra clave extern antes de una definición de variable le dirá al compilador que esta variable ya se ha definido en alguna parte, y que solo está declarando (es decir, nombrando) la variable para que otros archivos puedan usarla.

Por lo tanto, en su archivo de encabezado debe hacer que todas sus definiciones reenvíen declaraciones agregando la palabra clave extern .

extern MYSTRUCT Job_Grunt; extern MYSTRUCT *Grunt; extern MYSTRUCT Job_Uruk; extern MYSTRUCT *Uruk; extern int Other_data[100];

Y luego en uno (y solo uno) de sus archivos fuente, defina las variables normalmente:

MYSTRUCT Job_Grunt; MYSTRUCT *Grunt = &Job_Grunt; MYSTRUCT Job_Uruk; MYSTRUCT *Uruk = &Job_Grunt; int Other_data[100];


Como está declarando esas variables en el archivo de encabezado e incluyendo el archivo de encabezado en cada archivo C ++, cada archivo C ++ tiene su propia copia.

La forma habitual de evitar esto es no declarar ninguna variable dentro de los archivos de encabezado. En su lugar, declarelos en un único archivo C ++ y extern como extern en todos los otros archivos en los que pueda necesitarlos.

Otra forma en que he manejado esto antes, que algunas personas podrían considerar desagradable ... declararlas en el archivo de encabezado, así:

#ifdef MAINFILE #define EXTERN #else #define EXTERN extern #endif EXTERN MYSTRUCT Job_Grunt; EXTERN MYSTRUCT *Grunt = &Job_Grunt; EXTERN MYSTRUCT Job_Uruk; EXTERN MYSTRUCT *Uruk = &Job_Uruk;

Luego, en uno de sus archivos C ++, agregue un ...

#define MAINFILE

... antes de tus #include líneas de #include . Eso se encargará de todo, y es (en mi opinión personal) mucho más agradable que tener que redeclarar todas las variables en cada archivo.

Por supuesto, la verdadera solución es no usar variables globales en absoluto, pero cuando recién comienza es difícil de lograr.