Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Kaxperday en 9 Julio 2015, 13:03 pm



Título: Error al poner métodos de clase dentro de cabecera
Publicado por: Kaxperday en 9 Julio 2015, 13:03 pm
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
  1. struct host
  2. {
  3. public:
  4. u_char ip[4];
  5. u_char mac[6];
  6. };
  7.  
  8. class lista_usuarios
  9. {
  10. public:
  11. vector<host> usuarios;
  12. bool contiene_host(u_char* ip, u_char* mac);
  13. void insertar_host(u_char* ip, u_char* mac);
  14. };
  15.  
  16. void lista_usuarios::insertar_host(u_char* ip, u_char* mac)
  17. {
  18. int cont = 0, cant = 0;
  19.  
  20. for (int i = 0; i < usuarios.size(); i++)
  21. {
  22. cont = 0;
  23. for (int j = 0; j < 4; j++)
  24. if (ip[j] != usuarios[i].ip[j])
  25. {
  26. cont++;
  27. break;
  28. }
  29.  
  30. for (int j = 0; j < 6; j++)
  31. if (mac[j] != usuarios[i].mac[j])
  32. {
  33. cont++;
  34. break;
  35. }
  36. if (cont == 2)
  37. cant++;
  38. }
  39.  
  40. if (cant == usuarios.size())
  41. {
  42. host usuario;
  43. for (int j = 0; j < 4; j++)
  44. usuario.ip[j] = ip[j];
  45. for (int j = 0; j < 6; j++)
  46. usuario.mac[j] = mac[j];
  47. usuarios.push_back(usuario);
  48. }
  49. }

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

Citar
Error   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
  1. class lista_usuarios
  2. {
  3. private:
  4. vector<host> usuarios;
  5. public:
  6. //bool contiene_host(u_char* ip, u_char* mac);
  7. //void añadir_host(u_char* ip, u_char* mac);
  8. //void eliminar_host(u_char* ip, u_char* mac);
  9.  
  10. void lista_usuarios::añadir_host(u_char* ip, u_char* mac)
  11. {
  12. int cont = 0, cant = 0;
  13.  
  14. for (int i = 0; i < usuarios.size(); i++)
  15. {
  16. cont = 0;
  17. for (int j = 0; j < 4; j++)
  18. if (ip[j] != usuarios[i].ip[j])
  19. {
  20. cont++;
  21. break;
  22. }
  23.  
  24. for (int j = 0; j < 6; j++)
  25. if (mac[j] != usuarios[i].mac[j])
  26. {
  27. cont++;
  28. break;
  29. }
  30. if (cont == 2)
  31. cant++;
  32. }
  33.  
  34. if (cant == usuarios.size())
  35. {
  36. host usuario;
  37. for (int j = 0; j < 4; j++)
  38. usuario.ip[j] = ip[j];
  39. for (int j = 0; j < 6; j++)
  40. usuario.mac[j] = mac[j];
  41. usuarios.push_back(usuario);
  42. }
  43. };
  44.  
  45. };

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

Saludos.


Título: Re: Error al poner métodos de clase dentro de cabecera
Publicado por: ivancea96 en 9 Julio 2015, 13:58 pm
No, no es el mejor método. Ahora ese esa clase será compilada en cada archivo que la incluya.


Título: Re: Error al poner métodos de clase dentro de cabecera
Publicado por: Kaxperday en 9 Julio 2015, 14:21 pm
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.


Título: Re: Error al poner métodos de clase dentro de cabecera
Publicado por: ivancea96 en 9 Julio 2015, 15:03 pm
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.

Código:
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:

Código:
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.


Título: Re: Error al poner métodos de clase dentro de cabecera
Publicado por: Kaxperday en 9 Julio 2015, 18:52 pm
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.


Título: Re: Error al poner métodos de clase dentro de cabecera
Publicado por: crack81 en 9 Julio 2015, 19:13 pm
porque no pruebas las funciones inline pero aunque esto ultimas estan hechas para funcines pequeñas

te dejo algunos links:
http://codigomaldito.blogspot.mx/2005/12/funciones-inline.html (http://codigomaldito.blogspot.mx/2005/12/funciones-inline.html)
https://sites.google.com/site/jctovilla/programacion/c-c-para-linux-y-mac/funciones-inline-en-c-y-c-gnu (https://sites.google.com/site/jctovilla/programacion/c-c-para-linux-y-mac/funciones-inline-en-c-y-c-gnu)
http://es.ccm.net/faq/2823-la-funcion-inline-en-c (http://es.ccm.net/faq/2823-la-funcion-inline-en-c)


Título: Re: Error al poner métodos de clase dentro de cabecera
Publicado por: Kaxperday en 9 Julio 2015, 20:57 pm
Pues según esto ya lo estoy haciendo:

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

Código:
//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.