2012-01-04 13 views
6

Siempre que puedo compilar algo que # incluye una clase definida por el usuario, consigo estos errores de compilación que siempre se parecen: main.cpp: undefined reference to Complex::Complex(double, double)errores de inclusión de archivos (C++): referencia indefinida a ______

he reducido el problema a una conjunto de tres archivos extremadamente simples: main.cpp y, por ejemplo, Complex.hy Complex.cpp. Todavía obtengo errores de referencia indefinidos. Estoy desarrollando en Code :: Blocks en Windows pero obtengo lo mismo usando g ++ en Ubuntu. ¿Por qué pasó esto? Intenté construir Complex.cpp antes de main.cpp en Code :: Blocks, y probé g++ main.cpp Complex.cpp tanto como lo intenté con g++ main.cpp. Mismos errores todo el tiempo.

/*======== main.cpp ========*/ 
#include "Complex.h" 

int main() 
{ 
    Complex A(1.0, 1.0); 
    return 0; 
} 

/*======== Complex.h ========*/ 
#ifndef _COMPLEX_H 
#define _COMPLEX_H 

class Complex 
{ 
    public: 
    double x, y; 
    Complex(double real, double imag); 
}; 

#endif 

/*======== Complex.cpp ========*/ 
#include "Complex.h" 

Complex::Complex(double real, double imag) 
{ 
    x = real; 
    y = imag; 
} 

ed: ahora recibo diferentes errores, así que debo estar haciendo algo completamente incorrecto. Usando el mismo código que el anterior, obtengo:

main.cpp: in function 'int main()': 
main.cpp:5:5: error: 'Complex' was not declared in this scope 
main.cpp:5:13: error: expected ';' before 'A' 

Esto es extraño. Todo funcionó antes cuando tenía la clase en un archivo .cpp, pero eso es una "mala práctica", así que moví mis definiciones de clase a archivos .h y mantuve la implementación en archivos .cpp, y ahora nada funciona.

+1

También asegúrese de agregar "-I" a su línea de compilación. Quizás incluso "-I.", Si sus archivos .h están en el mismo directorio. – paulsm4

+3

Funciona para mí. Acabo de copiar tu 'main.cpp',' Complex.h', y 'Complex.cpp', y ejecuté' g ++ main.cpp Complex.cpp'. Creó 'a.out' muy bien. – ruakh

+1

Funciona para mí también. @ paulsm4: ¿no debería '.' estar en la ruta de inclusión predeterminada? (tenga en cuenta que está haciendo '#include" ... "', not '#include <...>') –

Respuesta

6

Eso no es un error de compilación, es un error de enlace. Debe asegurarse de vincular todos sus objetos. Puede hacerlo de varias maneras:

g++ main.cpp Complex.cpp 

Debería funcionar bien (y lo hace aquí cuando lo intenté con su ejemplo). También puede hacerlo en pasos:

g++ -c main.cpp 
g++ -c Complex.cpp 
g++ main.o Complex.o 
+0

En la pregunta, ya dice "He intentado' g ++ main.cpp Complex.cpp "' –

+0

@ AaronMcDaid, pero obviamente no lo ha hecho, ya que eso funcionará. Supongo que podría simplificar demasiado su ejemplo, también, pero eso tampoco lo ayudará a obtener la respuesta correcta. –

+0

Estoy de acuerdo. Ya había votado su respuesta como parece obviamente correcta :-) Supongo que estamos esperando los detalles del mensaje de error exacto. –

1

Mientras que nos queda en la oscuridad, si este es el código real (probablemente no, ya que trabaja para varios otros), vamos a comentar sobre el código en sí mismo un poco ... (Esto no tendrá ningún efecto en el error del enlazador)

  1. Nombres que comienzan con un guión bajo seguido de una letra mayúscula, por ej. _COMPLEX_H, están reservados para la implementación del compilador de C++ y la biblioteca estándar de C++. No los use.
  2. Las variables miembro se fabrican mejor private. Rara vez existe la necesidad de hacer un miembro de datos real public (a veces es razonable hacer miembros no funcionales public, por ejemplo, una clase de evento donde los usuarios pueden suscribir rellamadas, pero estos típicamente se comportan como funciones aunque técnicamente son objetos).
  3. La inicialización se realiza mejor en la lista de inicializadores de miembros. Es decir, el constructor sería algo como esto:

    Complejo :: Complejo (real doble, doble imagen): x (real), y (imag) {}

último , para aventurarse unos conjeturas lo que va mal con el código real para causar el problema que une:

  1. el constructor se define como inline. Obviamente, esto no funcionará a menos que la definición sea visible donde se usa el constructor.
  2. La declaración de Complex de alguna manera la convirtió en un espacio de nombre sin nombre y, por lo tanto, la definición pasa a definir una clase diferente a la vista por main.cpp.
Cuestiones relacionadas