• Domingo 15 de Diciembre de 2024, 01:56

Autor Tema:  Duda con Plantillas[C++]  (Leído 961 veces)

Karit

  • Nuevo Miembro
  • *
  • Mensajes: 1
    • Ver Perfil
Duda con Plantillas[C++]
« en: Jueves 30 de Diciembre de 2010, 04:59 »
0
Hola Buenas Noches a Todos!!

Tengo una duda acerca de las templates en C++.
Despues de leer varios tutoriales, por fin pude crear por mi cuenta una Lista Simplemente Enlazada utilizando plantillas y dos clases(Nodo y Lista).

Mi pregunta es:
¿Por que cuando tengo todo mi código junto en un solo archivo, cuando compilo y corro mi programa funciona perfecto, pero cuando separo el codigo en archivos de cabecera(.h y .cpp) mas el main.cpp mi compilador(g++) al momento del enlazado me tira varios errores?

Mi codigo TODO JUNTO el que si funciona es:
Código: Text
  1.  
  2. #include <iostream>
  3. using namespace std;
  4.  
  5. template <class Q>
  6. class Nodo{
  7.     private:
  8.         Q *MiDato;
  9.         Nodo<Q> *next;
  10.     public:
  11.         Nodo(Q nuevo){
  12.             next = NULL;
  13.             MiDato = new Q;
  14.             *MiDato = nuevo;
  15.         }
  16.         Nodo(void): MiDato(NULL), next(NULL) {}
  17.         ~Nodo(void){
  18.             delete MiDato;
  19.             next = NULL;
  20.         }
  21.         void set_data(Q nuevo){
  22.             MiDato = new Q;
  23.             *MiDato = nuevo;
  24.         }
  25.         void set_next(Nodo<Q> *s) { next = s; }
  26.         const Q get_data(void) const { return *MiDato; }
  27.         Nodo<Q> *get_next(void) { return next; }
  28.         void ShowAll(void) const{
  29.             Nodo<Q> *aux = next;
  30.  
  31.             cout << *MiDato << endl;
  32.             while(aux){
  33.                 cout << aux->get_data() << endl;
  34.                 aux = aux->get_next();
  35.             }
  36.         }
  37. };
  38.  
  39. template <class Q>
  40. class Lista{
  41.     private:
  42.         Nodo<Q> *inicio;
  43.         Nodo<Q> *final;
  44.         int tam;
  45.     public:
  46.         Lista(void): inicio(NULL), final(NULL), tam(0) {}
  47.         ~Lista(void){
  48.             Nodo<Q> *aux = inicio;
  49.  
  50.             if(!empty()){
  51.                 while(inicio){
  52.                     inicio = inicio->get_next();
  53.                     delete aux;
  54.                     aux = inicio;
  55.                 }
  56.             }
  57.             final = NULL;
  58.             tam = 0;
  59.         }
  60.         void add(Q nuevo){
  61.             Nodo<Q> *aux = new Nodo<Q>(nuevo);
  62.             if(empty()){
  63.                 inicio = aux;
  64.             }else{
  65.                 final->set_next(aux);
  66.             }
  67.             final = aux;
  68.             tam++;
  69.         }
  70.         int get_tam(void) const { return tam; }
  71.         bool empty(void) const{
  72.             return (inicio == NULL);
  73.         }
  74.         void Mostrar(void) const { inicio->ShowAll(); }
  75. };
  76.  
  77. int main(void){
  78.     Lista<int> Buena;
  79.     Lista<char> Mala;
  80.  
  81.     for(int i = 10; i < 21; i++){
  82.         Buena.add(i);
  83.     }
  84.     Mala.add('M');
  85.     Mala.add('A');
  86.     Mala.add('L');
  87.     Mala.add('A');
  88.  
  89.     cout << "Buena mide: " << Buena.get_tam() << endl;
  90.     Buena.Mostrar();
  91.     cout << "nMala mide: " << Mala.get_tam() << endl;
  92.     Mala.Mostrar();
  93.  
  94.     return 0;
  95. }
  96.  
  97.  

Y el error que me tira si creo los siguientes 5 archivos:
main.cpp, Nodo.cpp, Nodo.h, Lista.cpp y Lista.h
es:
Código: Text
  1.  
  2. $ g++ -c Nodo.cpp
  3. $ g++ -c Lista.cpp
  4. $ g++ main.cpp *.o
  5. /tmp/ccNbYLWk.o: In function `main':
  6. main.cpp:(.text+0x13): undefined reference to `Lista<int>::Lista()'
  7. main.cpp:(.text+0x1f): undefined reference to `Lista<char>::Lista()'
  8. main.cpp:(.text+0x39): undefined reference to `Lista<int>::add(int)'
  9. main.cpp:(.text+0x59): undefined reference to `Lista<char>::add(char)'
  10. main.cpp:(.text+0x6a): undefined reference to `Lista<char>::add(char)'
  11. main.cpp:(.text+0x7b): undefined reference to `Lista<char>::add(char)'
  12. main.cpp:(.text+0x8c): undefined reference to `Lista<char>::add(char)'
  13. main.cpp:(.text+0x98): undefined reference to `Lista<int>::get_tam() const'
  14. main.cpp:(.text+0xcc): undefined reference to `Lista<int>::Mostrar() const'
  15. main.cpp:(.text+0xd8): undefined reference to `Lista<char>::get_tam() const'
  16. main.cpp:(.text+0x10c): undefined reference to `Lista<char>::Mostrar() const'
  17. main.cpp:(.text+0x11d): undefined reference to `Lista<char>::~Lista()'
  18. main.cpp:(.text+0x130): undefined reference to `Lista<char>::~Lista()'
  19. main.cpp:(.text+0x144): undefined reference to `Lista<int>::~Lista()'
  20. main.cpp:(.text+0x160): undefined reference to `Lista<int>::~Lista()'
  21. collect2: ld devolvió el estado de salida 1
  22. $
  23.  
  24.  

¿Alguien me puede explicar que  sucede?

ProfesorX

  • Moderador
  • ******
  • Mensajes: 796
  • Nacionalidad: mx
    • Ver Perfil
Re: Duda con Plantillas[C++]
« Respuesta #1 en: Jueves 30 de Diciembre de 2010, 20:24 »
0
A ver como te lo explico, segun lei, no se permite separar las templates en dos archivos, si defines una template, procura que la definicion de la template quede en un solo archivo, asi te evitas de problemas.

Algunos compiladores permiten el uso de la palabra reservada export para poder separar el template en dos archivos, pero no todos los compiladores lo soportan, y ademas sera retirada del estandar, asi que su uso no se recomienda, mas explicacion el el siguiente FAQ (ingles):

http://www.parashift.com/c++-faq-lite/templates.html#faq-35.14

Entonces dicho eso, coloca cada template en un archivo, y no dos archivos para cada template, te dejo el codigo de como quedaria separando solo una template, te queda de tarea separar la otra, la idea seria 3 archivos solamente, main.cpp, lista.h y nodo.h:

Lista.h
Código: C++
  1.  
  2. #ifndef __LISTA_H__
  3. #define __LISTA_H__
  4.  
  5. #include "nodo.h"
  6.  
  7. template <class Q>
  8. class Lista{
  9. private:
  10.     Nodo<Q> *inicio;
  11.     Nodo<Q> *final;
  12.     int tam;
  13. public:
  14.     Lista(void): inicio(NULL), final(NULL), tam(0) {}
  15.     ~Lista(void){
  16.         Nodo<Q> *aux = inicio;
  17.  
  18.         if(!empty()){
  19.             while(inicio){
  20.                 inicio = inicio->get_next();
  21.                 delete aux;
  22.                 aux = inicio;
  23.             }
  24.         }
  25.         final = NULL;
  26.         tam = 0;
  27.     }
  28.     void add(Q nuevo){
  29.         Nodo<Q> *aux = new Nodo<Q>(nuevo);
  30.         if(empty()){
  31.             inicio = aux;
  32.         }else{
  33.             final->set_next(aux);
  34.         }
  35.         final = aux;
  36.         tam++;
  37.     }
  38.     int get_tam(void) const { return tam; }
  39.     bool empty(void) const{
  40.         return (inicio == NULL);
  41.     }
  42.     void Mostrar(void) const { inicio->ShowAll(); }
  43. };
  44.  
  45. #endif
  46.  
  47.  

main.cpp
Código: C++
  1.  
  2. #include <iostream>
  3. #include "nodo.h"
  4. #include "lista.h"
  5.  
  6. using namespace std;
  7.  
  8. int main(void){
  9.     Lista<int> Buena;
  10.     Lista<char> Mala;
  11.  
  12.     for(int i = 10; i < 21; i++){
  13.         Buena.add(i);
  14.     }
  15.     Mala.add('M');
  16.     Mala.add('A');
  17.     Mala.add('L');
  18.     Mala.add('A');
  19.  
  20.     cout << "Buena mide: " << Buena.get_tam() << endl;
  21.     Buena.Mostrar();
  22.     cout << "nMala mide: " << Mala.get_tam() << endl;
  23.     Mala.Mostrar();
  24.  
  25.     return 0;
  26. }
  27.  
  28.  

Saludos :)

NOTA:
==================================================================
Este foro es para ayudar, aprender, compartir... usenlo para eso,
NO SE RESUELVEN DUDAS POR MENSAJE PRIVADO Y MENOS POR CORREO
==================================================================