tipos - C++: error de definición múltiple para funciones globales en el archivo de encabezado
tipos de funciones en lenguaje c (5)
Esta función es global y está definida en el archivo de encabezado ( temporalmente quiero mantenerla allí).
El archivo de encabezado también constituye una clase particular que tiene funciones en línea y una de esas funciones llama a esta función global.
El archivo de origen no contiene ninguna aparición de la función global en cuestión.
¿Alguna pista sobre la causa del error?
Puedo publicar el código si alguien está interesado.
mainwindow.o: In function `tileForCoordinate(double, double, int)'':
mainwindow.cpp:(.text+0x310): multiple definition of `tileForCoordinate(double, double, int)''
main.o:main.cpp:(.text+0xd0): first defined here
moc_mainwindow.o: In function `qHash(QPoint const&)'':
moc_mainwindow.cpp:(.text+0x0): multiple definition of `qHash(QPoint const&)''
main.o:main.cpp:(.text+0x0): first defined here
moc_mainwindow.o: In function `tileForCoordinate(double, double, int)'':
moc_mainwindow.cpp:(.text+0x150): multiple definition of `tileForCoordinate(double, double, int)''
main.o:main.cpp:(.text+0xd0): first defined here
collect2: ld returned 1 exit status
make: *** [SimpleRouting] Error 1
Para una función global definida en un archivo de encabezado, declararla dentro de un espacio de nombres sin nombre debería / también funcionará. De acuerdo con C ++ Cómo programar por Deitel, en C ++, un espacio de nombres sin nombre es preferible a estático.
Para que pudieras hacer esto:
// /file GlobalFunctions.h
namespace // an un-named namespace
{
void GlobalFunctionOne() {...implementation...}
} // end un named namespace
Si coloca una función en el encabezado, se generará para cada archivo c / cpp que incluya ese encabezado que lleva a duplicados. Hacerlo en línea ayudará.
Editar, explicación
Los protectores de encabezado como #ifndef, #define ... # endif se suele llamar a la construcción solo para evitar la inclusión doble y recursiva en un solo archivo cpp. Esto es relevante en el caso de que un archivo fuente incluya los encabezados A y B y B también incluya A. La inclusión recursiva ocurriría si A también incluyera B.
Tu problema surge porque tienes varios archivos .cpp. Durante la compilación de un cpp, el compilador no conoce la existencia de los otros archivos cpp.
Tenga en cuenta que #include, #ifdef y friends son directivas de preprocesador. El preprocesamiento ocurre en los archivos de origen antes de la compilación (se piensa que a menudo se considera y se hace como parte del proceso de compilación). El preprocesador es básicamente un procesador de texto. Por ejemplo, un #include se reemplaza textualmente con el contenido del archivo de encabezado. El contenido de #ifdefs que se evalúa como falso se elimina del código. El compilador real obtiene un solo archivo grande que consiste en el cpp y todos los archivos de inclusión incluidos que se traducen en un archivo de objeto.
Tienes 2 opciones:
Márquelo como en línea, como se explica por nbt, o como estático.
inline tomará la implementación de la función global de la fuente y la copiará donde sea que se llame la función.
inline void global_func ()
{
...
}
static indicará al vinculador que no copie el código en el nuevo archivo de objeto, sino que solo haga referencia al mismo en el original.
static void global_func ()
{
...
}
marcarlo como en inline
:
inline void globalfunc() {
}
aunque hacerlo significa que ya no será estrictamente global; obtendrá una copia en cada unidad de traducción que usa el encabezado, pero el vinculador no se opondrá a esto.
#ifndef SOMESTRING
#define SOMESTRING
... header code
#endif
El código del encabezado solo se incluirá la primera vez.