Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: digimikeh en 7 Marzo 2019, 03:54 am



Título: Error de simbolo externo sin resolver (MSVS)
Publicado por: digimikeh en 7 Marzo 2019, 03:54 am
Hola amigos..

Estoy estudiando templates y no comprendo este comportamiento:

A continuacion la forma en que NO funciona (con esta forma obtengo el error que sale en el titulo)

Código
  1. //Clase.h
  2.  
  3. template <class TM>
  4. class Clase{
  5.  
  6.     TM num1, num2;
  7.  
  8. public:
  9.     Clase(TM n1, TM n2);
  10.     TM ObtenerMultiplicacion() const;
  11.  
  12. };
  13.  


Código
  1. //Clase.cpp
  2.  
  3. #include "Clase.h"
  4.  
  5. template <class TM>
  6. Clase<TM>::Clase(TM n1, TM n2){
  7.     this->num1 = n1;
  8.     this->num2 = n2;
  9. }
  10.  
  11.  
  12. template <class TM>
  13. TM Clase<TM>::ObtenerMultiplicacion() const{
  14.     return this->num1 * this->num2;
  15. }
  16.  


Sin embargo, con esta forma SI que funciona:
Código
  1. //Clase.h
  2.  
  3. template <class TM>
  4. class Clase{
  5.  
  6.     TM num1, num2;
  7.  
  8. public:
  9.     Clase(TM n1, TM n2);
  10.     TM ObtenerMultiplicacion() const;
  11.  
  12. };
  13.  
  14. template <class TM>
  15. Clase<TM>::Clase(TM n1, TM n2){
  16.     this->num1 = n1;
  17.     this->num2 = n2;
  18. }
  19.  
  20.  
  21. template <class TM>
  22. TM Clase<TM>::ObtenerMultiplicacion() const{
  23.     return this->num1 * this->num2;
  24. }
  25.  

Como verán, declarar la clase y definir sus miembros dentro del mismo archivo me funciona, pero si lo separo, no va... y me parece extraño, porque en el archivo Clase.cpp estoy incluyendo la cabecera con #include "Clase.h"

Que ha sucedido??


gracias de antemano.








Título: Re: Error de simbolo externo sin resolver (MSVS)
Publicado por: digimikeh en 7 Marzo 2019, 04:21 am
Ya entendí, me autorespondo por si alguien mas le interesa la razón..

Pasa que las funciones de clases que usen plantilla son siempre inline, es decir se deben declarar y definir dentro de la clase o al menos en el mismo archivo, creo que a este punto la extensión adecuada del archivo sería .hpp




Título: Re: Error de simbolo externo sin resolver (MSVS)
Publicado por: K-YreX en 7 Marzo 2019, 04:33 am
Como bien dices tiene que estar todo en el mismo fichero (o al menos que lo parezca). Para estos casos se suele usar la extensión <hpp> pero simplemente para ver más rápidamente a qué está haciendo referencia (pero si se usa <cpp> también funcionaría).
Para no tenerlo todo en el mismo fichero se suele crear la clase en el <clase.h> y las funciones miembro se implementan en <clase.hpp> y se incluye el <clase.hpp> dentro del <clase.h> en vez de al revés. Entonces como en el <main> incluimos <clase.h>, ya estaríamos incluyendo todo.
Código
  1. // clase.h
  2. #ifndef CLASE_H // opcional
  3. #define CLASE_H // opcional
  4. class Clase{
  5.  
  6. };
  7.  
  8. #include "clase.hpp"
  9. #endif // opcional


Título: Re: Error de simbolo externo sin resolver (MSVS)
Publicado por: digimikeh en 7 Marzo 2019, 18:18 pm
seria como una llamada anidada de archivos.. verdad?

main llama a Clase.h y ésta llama a Clase.hpp ?

Saludos...!"


Título: Re: Error de simbolo externo sin resolver (MSVS)
Publicado por: K-YreX en 7 Marzo 2019, 18:24 pm
Más o menos eso es.
Cuando haces un <#include fichero> al fin y al cabo es como si pegaras todo el contenido de <fichero> justo en la línea donde está el <include>. Entonces esto te permite implementarlo en distintos ficheros pero para la máquina a la hora de compilar es como si estuviera todo en el mismo. Es una forma de poder mantener la estructura de mantener las implementaciones en un fichero diferente a las declaraciones.