Ver Mensaje Individual
  #3 (permalink)  
Antiguo 30/10/2014, 10:34
eferion
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 10 años, 1 mes
Puntos: 204
Respuesta: Crear una máscara para ver determinados miembros de una estructura

Siempre hay soluciones.

En mi caso, yo primero declararía una clase que me permitiese manejar tipos de forma genérica (algo parecido a lo que echa de menos leosansan)

Código C++:
Ver original
  1. class Variant
  2. {
  3.   public:
  4.  
  5.     enum DataType
  6.     {
  7.       DTInt,
  8.       DTChar,
  9.       DTFloat
  10.     };
  11.  
  12.     Variant( )
  13.       : _type( DTInt )
  14.     {
  15.       _data.intData = 0;
  16.     }
  17.  
  18.     explicit Variant( int valor )
  19.       : _type( DTInt )
  20.     {
  21.       _data.intData = valor;
  22.     }
  23.  
  24.     explicit Variant( char valor )
  25.       : _type( DTChar )
  26.     {
  27.       _data.charData = valor;
  28.     }
  29.  
  30.     explicit Variant( float valor )
  31.       : _type( DTFloat )
  32.     {
  33.       _data.floatData = valor;
  34.     }
  35.  
  36.     DataType Type( ) const
  37.     { return _type; }
  38.  
  39.     Variant& operator=( int valor )
  40.     {
  41.       _type = DTInt;
  42.       _data.intData = valor;
  43.  
  44.       return *this;
  45.     }
  46.  
  47.     Variant& operator=( char valor )
  48.     {
  49.       _type = DTChar;
  50.       _data.charData = valor;
  51.  
  52.       return *this;
  53.     }
  54.  
  55.     Variant& operator=( float valor )
  56.     {
  57.       _type = DTFloat;
  58.       _data.floatData = valor;
  59.  
  60.       return *this;
  61.     }
  62.  
  63.     int ToInt( ) const
  64.     {
  65.       int to_return = 0;
  66.       switch ( _type )
  67.       {
  68.         case DTInt:
  69.           to_return = _data.intData;
  70.           break;
  71.  
  72.         case DTFloat:
  73.           to_return = static_cast< int >( _data.floatData );
  74.           break;
  75.       }
  76.  
  77.       return to_return;
  78.     }
  79.  
  80.     float ToFloat( ) const
  81.     {
  82.       float to_return = 0.0;
  83.       switch ( _type )
  84.       {
  85.         case DTFloat:
  86.           to_return = _data.floatData;
  87.           break;
  88.  
  89.         case DTInt:
  90.           to_return = static_cast< float >( _data.intData );
  91.           break;
  92.       }
  93.  
  94.       return to_return;
  95.     }
  96.  
  97.     char ToChar( ) const
  98.     {
  99.       char to_return = 0;
  100.  
  101.       switch ( _type )
  102.       {
  103.         case DTChar:
  104.           to_return = _data.charData;
  105.           break;
  106.       }
  107.  
  108.       return to_return;
  109.     }
  110.  
  111.   private:
  112.  
  113.     union Data
  114.     {
  115.       int intData;
  116.       char charData;
  117.       float floatData;
  118.     };
  119.  
  120.  
  121.     Data _data;
  122.     DataType _type;
  123. };

Se puede preparar para que admita más tipos, pero tampoco quería alargar demasiado el ejemplo.

Ahora necesitamos conectar esta clase con "cout" para poder imprimir el valor almacenado sin tener que andar haciendo cosas raras:

Código C++:
Ver original
  1. std::ostream& operator << ( std::ostream& stream, const Variant& variant )
  2. {
  3.   switch ( variant.Type( ) )
  4.   {
  5.     case Variant::DTInt:
  6.       stream << variant.ToInt( );
  7.       break;
  8.  
  9.     case Variant::DTChar:
  10.       stream << variant.ToChar( );
  11.       break;
  12.  
  13.     case Variant::DTFloat:
  14.       stream << variant.ToFloat( );
  15.       break;
  16.   }
  17.  
  18.   return stream;
  19. }

Ahora, por sencillez, modifico ligeramente la estructura. Prefiero eso a tener una función externa, pero para gustos los colores:

Código C++:
Ver original
  1. enum class Mascara
  2. {
  3.   Campo1,
  4.   Campo2,
  5.   Campo3
  6. };
  7.  
  8. struct datos
  9. {
  10.     int dato1;
  11.     float dato2;
  12.     char dato3;
  13.  
  14.     datos( )
  15.       : dato1( 3 ),
  16.         dato2( 3.85 ),
  17.         dato3( 'X' )
  18.     {
  19.     }
  20.  
  21.     Variant Valor( Mascara mascara ) const
  22.     {
  23.       Variant to_return;
  24.  
  25.       switch ( mascara )
  26.       {
  27.         case Mascara::Campo1:
  28.           to_return = dato1;
  29.           break;
  30.  
  31.         case Mascara::Campo2:
  32.           to_return = dato2;
  33.           break;
  34.  
  35.         case Mascara::Campo3:
  36.           to_return = dato3;
  37.           break;
  38.       }
  39.  
  40.       return to_return;
  41.     }
  42. };

Y ahora ya enlazamos todo esto con la aplicación:

Código C++:
Ver original
  1. void ver(const std::vector< Mascara >& mascara, const datos&D);
  2.  
  3. int main()
  4. {
  5.   datos D;
  6.   std::vector< Mascara > mascara { Mascara::Campo1, Mascara::Campo3 };
  7.   ver( mascara,D );
  8.   return 0;
  9. }
  10.  
  11. void ver(const std::vector< Mascara >& mascara, const datos&D)
  12. {
  13.   for ( auto it = mascara.begin( ); it != mascara.end( ); ++it )
  14.   {
  15.     std::cout << D.Valor( *it ) << " - ";
  16.   }
  17. }

Et voilá. Todo funciona a pedir de boca XD