Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Sobrecarga de << con template

Estas en el tema de Sobrecarga de << con template en el foro de C/C++ en Foros del Web. Hola, estoy creando una clase pila y de momento iba todo bien, pero cuando me he puesto a sobrecargar el operador <<... no encuentro solución. ...
  #1 (permalink)  
Antiguo 12/08/2011, 04:13
 
Fecha de Ingreso: marzo-2011
Mensajes: 94
Antigüedad: 13 años, 1 mes
Puntos: 3
Sobrecarga de << con template

Hola, estoy creando una clase pila y de momento iba todo bien, pero cuando me he puesto a sobrecargar el operador <<... no encuentro solución. Estuve mirando un rato por google y hay algo de información pero no entiendo muy bien... Aver si alguien me puede ayudar. Dejo el código para que se vean bien los errores al compilar:

Código C++:
Ver original
  1. #include <iostream>
  2. #include <new>
  3. using namespace std;
  4.  
  5. template< class T >
  6. class PILA_DATOS{
  7.       template< class t > friend class PILA;
  8.       private:
  9.               T nodo;
  10.               PILA_DATOS< T > *ptrPilaSiguiente;
  11.              
  12. };
  13.  
  14. template< class T >
  15. class PILA{
  16.       friend ostream &operator<< <T>( ostream &, const PILA< T > & );
  17.       public:
  18.              PILA();
  19.              PILA< T > &empujarPila ( const T& );
  20.              PILA< T > &sacarPila ();
  21.       private:
  22.               PILA_DATOS< T > *ptrPila;
  23.               bool estaVacia ();
  24.              
  25. };
  26.  
  27. template< class T >
  28. PILA< T >::PILA (){
  29.      
  30.       ptrPila = NULL;
  31.      
  32. }
  33.  
  34. template< class T >
  35. bool PILA< T >::estaVacia (){
  36.      
  37.      return ( ptrPila == NULL ? true : false );
  38.      
  39. }
  40.  
  41. template< class T >
  42. PILA< T > &PILA< T >::empujarPila ( const T &a ){
  43.        
  44.         if ( estaVacia () ){
  45.              
  46.              ptrPila = new PILA_DATOS< T >;
  47.              ptrPila->nodo = a;
  48.              ptrPila->ptrPilaSiguiente = NULL;
  49.              
  50.         }
  51.        
  52.         else{
  53.              
  54.              PILA_DATOS< T > *nuevaPila;
  55.              nuevaPila= new PILA_DATOS< T >;
  56.              nuevaPila->nodo = a;
  57.              nuevaPila->ptrPilaSiguiente = ptrPila;
  58.              ptrPila = nuevaPila;
  59.              
  60.         }
  61.        
  62.         return *this;
  63.        
  64. }
  65.  
  66. template< class T >
  67. PILA< T > &PILA< T >::sacarPila (){
  68.      
  69.       PILA_DATOS< T > *temp;
  70.       temp = ptrPila;
  71.       ptrPila = ptrPila->ptrPilaSiguiente;
  72.       delete temp;
  73.       return *this;
  74.      
  75. }
  76.  
  77. template< class T >
  78. ostream &operator<<( ostream &salida, const PILA< T > &pila ){
  79.        
  80.         PILA_DATOS< T > *a = pila.ptrPila;
  81.         while ( a != NULL ){
  82.              
  83.               salida << a->nodo << "->";
  84.               a = a->ptrPilaSiguiente;
  85.              
  86.         }
  87.         salida << "NULL\n";
  88.         return salida;
  89.        
  90. }
  91.  
  92. int main (){
  93.    
  94.     PILA< int > a;
  95.     a.empujarPila (2).empujarPila (3).empujarPila(23).empujarPila (25);
  96.     cout << a;
  97.     a.sacarPila().sacarPila();
  98.     cout << a;
  99.    
  100.     getchar();
  101.    
  102.     return 0;
  103.    
  104. }

Muchas gracias!
  #2 (permalink)  
Antiguo 12/08/2011, 06:09
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 15 años, 10 meses
Puntos: 61
Respuesta: Sobrecarga de << con template

Sugiero:

template <class T> class PILA;

antes de la clase PILA_DATOS

Usar

template <class U> friend ostream &operator<< ( ostream &, const PILA< U > & );

dentro de la clase PILA

y no usar a->nodo o a->ptrPilaSiguiente en la implementacion del operador <<

a->nodo da a entender que un objeto de la clase a tiene visibilidad de la clase de datos y eso no es lo que hace el friend de la funcion operador. El friend de la funcion operador solo tiene acceso a PILA y aunque esta sea friend de otra clase, la amistad solo te dura 1 nivel. Al menos asi lo entiendo yo.

Puedes inspirarte en los metodos begin(), end() e iteradores de la STL
  #3 (permalink)  
Antiguo 12/08/2011, 08:41
 
Fecha de Ingreso: marzo-2011
Mensajes: 94
Antigüedad: 13 años, 1 mes
Puntos: 3
Respuesta: Sobrecarga de << con template

No entiendo eso de usar template <class T> class PILA ni template <class U> friend ostream &operator<< ( ostream &, const PILA< U > & );

Con respecto a lo de friend, puedo entonces declarar que es amiga de PILA y PILA_DATOS ?

Un saludo!
  #4 (permalink)  
Antiguo 12/08/2011, 09:16
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 15 años, 10 meses
Puntos: 61
Respuesta: Sobrecarga de << con template

No es, para mi, corto de explicar, a menos que lo que está a continuación sirva:

Recuerda que la funcion amiga no es parte de la clase, solo estás declarando la amistad desde la clase hacia la funcion. La funcion igual sera necesaria definirla afuera. Por lo tanto ella necesita ser un template tambien. Para no ocultar la T de la clase con la T de la funcion, usas otra letra, como U. Si usas la misma T el compilador reclamara que una T oculta la otra o algo similar.
  #5 (permalink)  
Antiguo 13/08/2011, 07:52
 
Fecha de Ingreso: marzo-2011
Mensajes: 94
Antigüedad: 13 años, 1 mes
Puntos: 3
Respuesta: Sobrecarga de << con template

Bueno, al final he hecho esto:

Código C++:
Ver original
  1. #include <iostream>
  2. #include <new>
  3. using namespace std;
  4.  
  5. template< class T >
  6. class PILA_DATOS{
  7.       template< class t > friend class PILA;
  8.      
  9.       public:
  10.              template< class U > friend ostream& operator<< ( ostream &,
  11.              const PILA_DATOS< U > & );
  12.              PILA_DATOS< T >* getPtrPilaSig ();
  13.       private:
  14.               T nodo;
  15.               PILA_DATOS< T > *ptrPilaSiguiente;
  16.              
  17. };
  18.  
  19. template< class U > ostream& operator<< ( ostream &salida,
  20. const PILA_DATOS< U > &a ){
  21.      
  22.       salida << a.nodo;
  23.       return salida;
  24.      
  25. }
  26.  
  27. template< class T >
  28. PILA_DATOS< T >* PILA_DATOS< T >::getPtrPilaSig (){
  29.            
  30.             return ptrPilaSiguiente;
  31.            
  32. }
  33.  
  34. template< class T >
  35. class PILA{
  36.       public:
  37.              PILA();
  38.              PILA< T > &empujarPila ( const T& );
  39.              PILA< T > &sacarPila ();
  40.              PILA< T > &mostrarPila ();
  41.              template< class U > friend ostream& operator<< ( ostream &,
  42.              const PILA< U > & );
  43.       private:
  44.               PILA_DATOS< T > *ptrPila;
  45.               bool estaVacia ();
  46.              
  47. };
  48.  
  49. template< class T >
  50. PILA< T >::PILA (){
  51.      
  52.       ptrPila = NULL;
  53.      
  54. }
  55.  
  56. template< class T >
  57. bool PILA< T >::estaVacia (){
  58.      
  59.      return ( ptrPila == NULL ? true : false );
  60.      
  61. }
  62.  
  63. template< class T >
  64. PILA< T > &PILA< T >::empujarPila ( const T &a ){
  65.        
  66.         if ( estaVacia () ){
  67.              
  68.              ptrPila = new PILA_DATOS< T >;
  69.              ptrPila->nodo = a;
  70.              ptrPila->ptrPilaSiguiente = NULL;
  71.              
  72.         }
  73.        
  74.         else{
  75.              
  76.              PILA_DATOS< T > *nuevaPila;
  77.              nuevaPila= new PILA_DATOS< T >;
  78.              nuevaPila->nodo = a;
  79.              nuevaPila->ptrPilaSiguiente = ptrPila;
  80.              ptrPila = nuevaPila;
  81.              
  82.         }
  83.        
  84.         return *this;
  85.        
  86. }
  87.  
  88. template< class T >
  89. PILA< T > &PILA< T >::sacarPila (){
  90.      
  91.       PILA_DATOS< T > *temp;
  92.       temp = ptrPila;
  93.       ptrPila = ptrPila->ptrPilaSiguiente;
  94.       delete temp;
  95.       return *this;
  96.      
  97. }
  98.  
  99. template< class T >
  100. PILA< T > &PILA< T >::mostrarPila (){
  101.      
  102.       PILA_DATOS< T > *a = ptrPila;
  103.       while ( a != NULL ){
  104.             cout << a->nodo << "->";
  105.             a = a->ptrPilaSiguiente;
  106.       }
  107.       cout << "NULL" << endl;
  108.       return *this;
  109.      
  110. }
  111.  
  112. template< class U > ostream& operator<< ( ostream &salida,
  113. const PILA< U > &a ){
  114.      
  115.       PILA_DATOS< U > *b = a.ptrPila;
  116.       while ( b != NULL ){
  117.             salida << *b << "->";
  118.             b = b->getPtrPilaSig ();
  119.       }
  120.       salida << "NULL" << endl;
  121.       return salida;
  122.      
  123. }
  124.  
  125. int main (){
  126.    
  127.     PILA< float > a;
  128.     a.empujarPila (2.5).empujarPila (3).empujarPila(23).empujarPila (25);
  129.     cout << a;
  130.     a.sacarPila().sacarPila();
  131.     cout << a;
  132.    
  133.     getchar();
  134.     return 0;
  135.    
  136. }

Compila y funciona, pero me gustaría saber si se puede hacer de alguna forma que no requiera la funcion miembro de PILA_DATOS getPtrPilaSig. Además no entiendo por qué hay que declarar una clase amigo o una función amigo como una plantilla con un "tipo diferente" , es decir en lugar de T declarar t o U. Cómo sabe el compilador que U o t es igual al T del template actual?

Un saludo!!

Etiquetas: sobrecarga, template
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 17:58.