Error al poner métodos de clase dentro de cabecera

Iniciado por Kaxperday, 9 Julio 2015, 13:03 PM

0 Miembros y 1 Visitante están viendo este tema.

Kaxperday

Hola de nuevo  :xD :xD, tengo una clase definida en la cabecera, pero al poner sus métodos dentro de la cabecera (archivo ".h") me da error sin embargo al poner sus métodos en el ".cpp" no da error, ¿que solución puedo tomar?.

Código (cpp) [Seleccionar]
struct host
{
public:
u_char ip[4];
u_char mac[6];
};

class lista_usuarios
{
public:
vector<host> usuarios;
bool contiene_host(u_char* ip, u_char* mac);
void insertar_host(u_char* ip, u_char* mac);
};

void lista_usuarios::insertar_host(u_char* ip, u_char* mac)
{
int cont = 0, cant = 0;

for (int i = 0; i < usuarios.size(); i++)
{
cont = 0;
for (int j = 0; j < 4; j++)
if (ip[j] != usuarios[i].ip[j])
{
cont++;
break;
}

for (int j = 0; j < 6; j++)
if (mac[j] != usuarios[i].mac[j])
{
cont++;
break;
}
if (cont == 2)
cant++;
}

if (cant == usuarios.size())
{
host usuario;
for (int j = 0; j < 4; j++)
usuario.ip[j] = ip[j];
for (int j = 0; j < 6; j++)
usuario.mac[j] = mac[j];
usuarios.push_back(usuario);
}
}


Cuando pongo esto en "capturador.h" me sale el siguiente error:

CitarError   8   error LNK2005: ya se definió "public: void __thiscall lista_usuarios::insertar_host(unsigned char *,unsigned char *)" (?insertar_host@lista_usuarios@@QAEXPAE0@Z) en main.obj

Ya os digo que simplemente al mover el método a el ".cpp" se corrige el error, pero ¿porque no me deja meterlo en la cabecera? No hay más definiciones que yo sepa XD

Saludos y gracias como siempre.

Edito_ Estoy en ello:

https://support.microsoft.com/en-us/kb/148652/es

Edito: Solucionado de rara manera ahora entiendo el error:

http://www.cplusplus.com/forum/beginner/30800/

El último comentario lo explica, lo que hice fue meter el metodo en el cuerpo de la funcion y quitar su declaracion cambiandola por la del cuerpo del método:

Código (cpp) [Seleccionar]
class lista_usuarios
{
private:
vector<host> usuarios;
public:
//bool contiene_host(u_char* ip, u_char* mac);
//void añadir_host(u_char* ip, u_char* mac);
//void eliminar_host(u_char* ip, u_char* mac);

void lista_usuarios::añadir_host(u_char* ip, u_char* mac)
{
int cont = 0, cant = 0;

for (int i = 0; i < usuarios.size(); i++)
{
cont = 0;
for (int j = 0; j < 4; j++)
if (ip[j] != usuarios[i].ip[j])
{
cont++;
break;
}

for (int j = 0; j < 6; j++)
if (mac[j] != usuarios[i].mac[j])
{
cont++;
break;
}
if (cont == 2)
cant++;
}

if (cant == usuarios.size())
{
host usuario;
for (int j = 0; j < 4; j++)
usuario.ip[j] = ip[j];
for (int j = 0; j < 6; j++)
usuario.mac[j] = mac[j];
usuarios.push_back(usuario);
}
};

};


Funciona, aunque no creo que sea el mejor método (pero al menos ya lo tengo en el ".h").

Saludos.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

ivancea96

No, no es el mejor método. Ahora ese esa clase será compilada en cada archivo que la incluya.

Kaxperday

y entonces no hay alguna forma de meterlo en un archivo de cabecera (todo el contenido de la clase) sin que eso ocurra, o algún método más eficiente?.

Saludos.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

ivancea96

El archivo de cabecera es pura información sobre la clase y sus métodos y campos. Esa es la teoría de cómo debería ser. Obviamente luego puedes hacer con ella lo que quieras.

clase.h
clase.cpp
main.cpp


clase.cpp se compila. Incluye clase.h para saber las clases y métodos -> clase.o, con sus funciones y clases
main.cpp se compila, e incluye clase.h para saber las clases y métodos, que son las que usarás -> main.o
main.o + clase.o -> final.exe

Si hicieras: main.o -> final.exe, las funciones que usa que coge de clase.h no se encontrarían, y saltarían errores del linker.


Una vez visto eso:

clase.h (como lo tienes tú, con las funciones desarrolladas)
main.cpp

main.cpp se compila. Incluye chase.h. Al incluirla, todo lo que tiene dentro se compila junto a main.cpp -> main.exe


El problema de esto es que puede haber problemas si incluyes la cabecera multiples veces, en multiples archivos. Para hacer algo puntual, es factible, pero para hacer un proyecto importante, no.

Kaxperday

Entonces quieres decir que lo mejor es ponerlo en el ".cpp", lo imaginaba pero no se me hace "bonito" verlo así. De todas formas lo tendré en cuenta para no hacerlo compilar más de una vez.

Saludos.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

crack81

Si C/C++ es el padre de los lenguajes entonces ASM es dios.

Kaxperday

Pues según esto ya lo estoy haciendo:

http://codigomaldito.blogspot.mx/2005/12/funciones-inline.html

//Clase con funciones INLINE
#include <iostream>
using std::cout;
using std::endl;
class Prueba
{
private:
  int x;
public:
  Prueba(int val = 0)
    {
      x = val;
    }
  void Establecer(int valor)
  {
    x = valor;
  }
  int Obtener ()
  {
    return x;
  }
};


Aunque como dice ivancea es mejor dejar sólo las declaraciones en la cabecera y las definiciones en el cpp.  :P

Saludos.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.