Ver Mensaje Individual
  #9 (permalink)  
Antiguo 15/04/2015, 07:27
eferion
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 10 años, 1 mes
Puntos: 204
Respuesta: Diferenciar entrada de datos por consola

Cita:
Iniciado por vangodp Ver Mensaje
jajaja ve! Era un 'if else' de templates jaja. Pfff Que complicadas son las plantillas cachis.

He visto pocas cosas con platillas(siempre intento evitarlas >_<), pero realmente el que las sabe sacar partido hacen maravillas con ellas. Otro día vi como se hacia un un nodo de una lista simples de una estructura con plantillas, no tenia ni idea de que se pudiera hacer esto. jajaja

A ver si un día llego a las plantillas, pero eso me parece ya muy hard para mi. >_<
La clave es pensar de forma diferente, conocer sus limitaciones (de los templates) y cómo sortear dichas limitaciones... y luego dejar todo bien documentado para no volverse loco.

vangodp, tu comentario me ha inspirado. Un ejemplo de una lista simple usando templates... la gracia está en que admite diferentes tipos de datos:

Código C++:
Ver original
  1. #include <iostream>
  2. #include <string>
  3.  
  4. class NodoBase
  5. {
  6.   public:
  7.  
  8.     NodoBase( )
  9.       : _siguiente( nullptr )
  10.     { }
  11.  
  12.     virtual ~NodoBase( )
  13.     { }
  14.  
  15.     void SetSiguiente( NodoBase* siguiente )
  16.     { _siguiente = siguiente; }
  17.  
  18.     NodoBase* Siguiente( ) const
  19.     { return _siguiente; }
  20.  
  21.     virtual void Pintar( std::ostream& out ) const = 0;
  22.  
  23.   private:
  24.  
  25.     NodoBase* _siguiente;
  26. };
  27.  
  28. template< typename _TYPE_ >
  29. class Nodo : public NodoBase
  30. {
  31.   public:
  32.     Nodo( _TYPE_ valor )
  33.       : _valor( valor )
  34.     { }
  35.  
  36.     ~Nodo( )
  37.     { }
  38.  
  39.     virtual void Pintar( std::ostream& out ) const
  40.     { out << _valor; }
  41.  
  42.   private:
  43.  
  44.     _TYPE_ _valor;
  45. };
  46.  
  47. class Lista
  48. {
  49.   public:
  50.  
  51.     Lista( )
  52.       : _primero( nullptr )
  53.     { }
  54.  
  55.     virtual ~Lista( )
  56.     {
  57.       while( _primero )
  58.       {
  59.         NodoBase* siguiente = _primero->Siguiente( );
  60.         delete _primero;
  61.         _primero = siguiente;
  62.       }
  63.     }
  64.  
  65.     template< class _TYPE_ >
  66.     void NuevoItem( _TYPE_ valor )
  67.     {
  68.       NodoBase* nuevoNodo = new Nodo<_TYPE_>( valor );
  69.  
  70.       if ( !_primero )
  71.         _primero = nuevoNodo;
  72.       else
  73.       {
  74.         NodoBase* nodo = _primero;
  75.         while( nodo->Siguiente( ) )
  76.           nodo = nodo->Siguiente( );
  77.  
  78.         nodo->SetSiguiente( nuevoNodo );
  79.       }
  80.     }
  81.  
  82.     void Pintar( std::ostream& out )
  83.     {
  84.       if ( !_primero )
  85.       {
  86.         out << "Lista vacía" << std::endl;
  87.         return;
  88.       }
  89.  
  90.       _primero->Pintar( out );
  91.       NodoBase* nodo = _primero->Siguiente( );
  92.       while( nodo )
  93.       {
  94.         out << " -> ";
  95.         nodo->Pintar( out );
  96.         nodo = nodo->Siguiente( );
  97.       }
  98.  
  99.       out << std::endl;
  100.     }
  101.  
  102.   private:
  103.  
  104.     NodoBase* _primero;
  105. };
  106.  
  107. int main( )
  108. {
  109.   Lista lista;
  110.  
  111.   lista.NuevoItem( 1 );
  112.   lista.NuevoItem( 'c' );
  113.   lista.NuevoItem( "prueba" );
  114.   lista.NuevoItem( 4.56 );
  115.  
  116.   lista.Pintar( std::cout );
  117. }

¿Por qué uso "NodoBase"?? por dos razones:

* Un template no puede tener un método virtual puro
* Las especializaciones de un template no tienen herencia común, class<int> no hereda, de ninguna forma, de class<T>, por lo que necesito un mecanismo que me permita incrustar tipos de "nodos" diferentes a partir de una clase común.

Un saludo.

Última edición por eferion; 15/04/2015 a las 07:44