2010-11-09 2 views
24

No puedo entender por qué esto no funciona. Pondré mis tres archivos y posiblemente alguien me diga por qué está arrojando este error. Estoy usando g ++ para compilar el programa.C++ referencia indefinida a la función definida

Programa:

#include <iostream> 
#include "h8.h" 

using namespace std; 

int main() 
{ 
    char sentence[MAX_SENTENCE_LENGTH]; 
    char writeTo[] = "output.txt"; 
    int distanceTo,likePosition, length, numWords; 
    cout << "ENTER A SENTENCE! "; 
    cin.getline(sentence, 299); 
    length = strlen(sentence); 
    numWords = wordCount(sentence, length); 
    for(int x = 0; x < 3; ++x) 
    { 
    likePosition = likePos(numWords); 
    distanceTo = lengthTo(sentence, likePosition, length); 
    insertLike(sentence, distanceTo, length, writeTo); 
    } 
    return 0; 
} 

archivo Función: archivo

void insertLike(const char sentence[], const int lengthTo, const int length, char writeTo[]) 
{ 
    char part1[MAX_SENTENCE_LENGTH], part2[MAX_SENTENCE_LENGTH]; 
    char like[] = " like "; 
    for(int y = 0; y < lengthTo; ++y) 
    part1[y] = sentence[y]; 
    for(int z = lengthTo+1; z < length - lengthTo; ++z) 
    part2[z] = sentence[z]; 
    strcat(part1, like); 
    strcat(part1, part2); 
    writeToFile(sentence, writeTo); 
    return; 
} 

Cabecera:

void insertLike(const char sentence[], const int lengthTo, const int length, const char writeTo[]); 

El error está exactamente:

undefined reference to 'insertLike(char const*, int, int, char const*)' 
collect2: ld returned 1 exit status 

Respuesta

18

La declaración y definición de insertLike son diferentes

En el archivo de cabecera:

void insertLike(const char sentence[], const int lengthTo, const int length,const char writeTo []);

En su 'archivo de función':

void insertLike(const char sentence[], const int lengthTo, const int length,carbón writeTo []);

C++ permite la sobrecarga de funciones, donde se puede tener múltiples funciones/métodos con el mismo nombre, siempre y cuando tienen argumentos distintos. Los tipos de argumentos son parte de la firma de la función.

En este caso, insertLike que toma const char* como su cuarto parámetro y insertLike que toma char * como su cuarto parámetro son funciones diferentes.

+0

Estoy totalmente/headfloor ahora mismo. – Mashew

+21

A veces solo se necesita un conjunto extra de globos oculares, hombre. :) Recuerdo que cuando estaba aprendiendo C, y me pasaba medio día golpeándome la cabeza con el teclado con frustración, mi suegro volvía a casa y me señalaba por encima del hombro: "Te falta un punto y coma". ahí." >.> – Mud

+6

Bueno, nunca tuve un suegro. Probablemente por eso pasé más de medio día golpeando mi cabeza en el teclado con frustración :-) –

14

necesita compilar y vincular todos sus archivos fuente juntos:

g++ main.c function_file.c 
+2

Me doy cuenta de que tengo casi 5 años, pero soy un novato total en C++ y esto funcionó para mí. Gracias. –

+1

Lo mismo aquí, estaba tratando de compilar un código VS en una máquina Debian y acaba de encontrar esto, ¡gracias por la respuesta! Incluso puede hacer 'g ++ * .c', según http://stackoverflow.com/questions/3202136/using-g-to-compile-multiple-cpp-and-h-files#comment3301067_3202161 –

18

Aunque los carteles anteriores cubrían su error particular, puede obtener errores del vinculador de "referencia no definida" al intentar compilar el código C con g ++, si no le dice al compilador que use el enlace C.

Por ejemplo, usted debe hacer esto en los archivos de cabecera C:

extern "C" { 

... 

void myfunc(int param); 

... 

} 

Para hacer 'myfunc' disponible en los programas en C++.

Si todavía también desea utilizar esto desde C, envuelva el extern "C" { y } en #ifdef __cplusplus condicionales del preprocesador, como

#ifdef __cplusplus 
extern "C" { 
#endif 

De esta manera, el bloque extern sólo será “saltado” cuando se utiliza un compilador de C .

+0

Gracias, esto me impidió volverme loco. ¡Justo a tiempo! – Robert

+0

¡El vinculador realmente debería verificar este caso y decirle que hay una versión no marcada de la función definida! – jtbr

+0

Gracias, esto lo resolvió para mí. También necesitaba para agregar: #ifdef __cplusplus extern "C" { #endif y #ifdef __cplusplus } #endif en la parte superior y la parte inferior de mis archivos de cabecera C, ya que se hace referencia por código C++ y C – karora

2

Esto también podría suceder si está utilizando CMake.Si ha creado una nueva clase y desea instanciarla, en la llamada al constructor recibirá este error -incluso cuando el encabezado y los archivos cpp sean correctos- si no ha modificado CMakeLists.txt en consecuencia.

Con CMake, cada vez que cree una nueva clase, antes de usarlo la cabecera, los cpp archivos y cualquier otro archivo compilables (como Qt ui archivos) hay que añadir a CMakeLists.txt y luego volver a ejecutar cmake . donde se almacena CMakeLists.txt .

Por ejemplo, en este archivo CMakeLists.txt:

cmake_minimum_required(VERSION 2.8.11) 

project(yourProject) 

file(GLOB ImageFeatureDetector_SRC *.h *.cpp) 

### Add your new files here ### 
add_executable(yourProject YourNewClass.h YourNewClass.cpp otherNewFile.ui}) 

target_link_libraries(imagefeaturedetector ${SomeLibs}) 

Si está utilizando el comando file(GLOB yourProject_SRC *.h *.cpp) continuación, sólo tiene que volver a ejecutar cmake . sin modificar CMakeLists.txt.

+0

'make rebuild_cache' es otra forma de forzar la reconfiguración. Además, es por eso que no construyes tus CMakeLists fuera de nombre de archivo 'GLOB's. Hay una razón por la que se llaman listas de ** CMake ** después de todo. – ulidtko