[C con Clase] Serializar variables

Ferran Ferri ferranferri en gmail.com
Sab Mar 13 19:14:30 CET 2010


Dudas resueltas, muchisimas gracias
Ferran



2010/3/13 Steven Davidson <srd4121 en njit.edu>:
> Hola Ferrán,
>
> Ferran Ferri wrote:
>>
>> Hola Steven,
>> muchas grecias por tu respuesta. Mi forma de hacerlo cuando fallaba
>> era asi:
>>
>> void toArray(unsigned char* data)
>> {
>>        int a = 3;
>>        long b = 444;
>>        int *pA = &a;
>>        long *pB = &b;
>>
>>        cout << "Valor de *pA " <<*pA <<endl;
>>        memcpy(data,(unsigned char*)pA,sizeof(int));
>>        data+=sizeof(int);
>>        cout << "Valor de *pB " <<*pB <<endl;
>>        memcpy(data,(unsigned char*)pB,sizeof(long));
>>        data+=sizeof(long);
>> }
>> Y fallaba por el incremento de data (lo hacia mal aunque no se por
>> que. Asi se corregia:
>>
>
> No. No es cierto. He probado tu función y funciona (valga la redundancia)
> perfectamente.
>
>> void toArray(unsigned char* data)
>> {
>>        int a = 3;
>>        long b = 444;
>>        int *pA = &a;
>>        long *pB = &b;
>>
>>        cout << "Valor de *pA " <<*pA <<endl;
>>        memcpy(data,(unsigned char*)pA,sizeof(int));
>>        cout << "Valor de *pB " <<*pB <<endl;
>>        memcpy(data + sizeof(int),(unsigned char*)pB,sizeof(long));
>>        data+=sizeof(long);
>> }
>>
>
> Esta versión es prácticamente la misma que la primera. Eso sí, la última
> asignación no es necesaria:
> datos += sizeof(long);
>
> ya que hemos terminado.
>
>> Tu solucion, sin embargo, me parece mucho mas elegante. Pero me
>> genera dudas. Que diferencia hay entre reinterpret cast y static cast
>> ademas de que static cast fuerza el que se haga en tiempo de
>
> El operador 'reinterpet_cast' sirve para dejar la secuencia de bits intacta.
> Esto significa que el tipo de dato de tal secuencia de bits varía. El
> operador 'static_cast' puede modificar los bits yendo de un tipo a otro.
>
>> compilacion? Y la segunda duda es que cuando se acumulan variables no
>> puedo ir sumando cada vez para ponerme en la posicion del array.
>> Serviria algo como
>> *reinterpret_cast< int * >( data++ ) = a;
>> *reinterpret_cast< long * >( data++ ) = b;  // si tuvieramos que meter
>> mas variables
>> Al haber reinterpretado el puntero, y hacer post incremento,
>> avanzariamos un int en la primera sentencia y un long en la segunda,
>> no es asi?
>>
>
> No. Nunca se cambia el tipo de la variable sino el tipo del valor. La
> variable 'data' ha sido definida como 'unsigned char *' y nunca se puede
> cambiar. Lo que sí podemos hacer es acceder a su valor y cambiar su tipo. En
> la práctica, el compilador generará una variable temporal con el tipo
> indicado y con el valor original. Por ejemplo,
>
> double b = -1.3;
> int a = static_cast< int >( b );
>
> El compilador internamente hará algo así:
>
> double b = -1.3;
> int __temp = static_cast< int >( -1.3 );
> int a = __temp;
>
> Como puedes ver, 'b' nunca cambiará ni tampoco el valor que contiene. Lo que
> se hace es crear otro valor basándose en el valor de 'b', pero sin modificar
> éste.
>
> Dicho todo esto, la respuesta a tu pregunta es que al incrementar 'data',
> este puntero apuntará al siguiente elemento. Como cada elemento es 'unsigned
> char', el incremento será al siguiente 'char' que equivale al siguiente
> byte. Para hacer el incremento a la siguiente dirección de memoria posterior
> a 'int', tendrías que sumar ese tamaño en byte, ya que 'char' siempre ocupa
> 1 byte. Esto es,
>
> *reinterpret_cast< int * >( data ) = a;
> data += sizeof(int);
>
> *reinterpret_cast< long * >( data ) = b;
> data += sizeof(long);
>
>> La tercera es mas offtopic. Si la funcion toArray la tengo en una
>> clase (es un metodo), donde deberia hacer la reserva de memoria. El
>> borrado es responsabilidad de quien usa la funcion cuando ya no la
>> necesita. Pero la creacion podriamos hacerla dentro de la funcion
>> (esta seria mi eleccion), puesto que ya sabemos cuanto espacio
>> necesitamos, o exigir que se cree fuera, y comprobar que o sea null,
>> puesto que tenemos que separar responsabilidades. Que opinais?
>
> No es una buena práctica crear efectos secundarios en una función. Lo que
> propones justamente crea este efecto secundario de adjudicar memoria
> dinámicamente. Aconsejo que el array se cree fuera y así delegamos la
> responsabilidad al invocador de esta función miembro.
>
> Claro está, al usar clases, recomendaría usar un objeto de una clase
> contenedora y si esta clase usa memoria dinámicamente, entonces mejor que
> mejor. Por ejemplo, puedes usar la clase-plantilla 'vector'. Por otro lado,
> posiblemente esto no sea lo que quieres, ya que 'toArray()' no representaría
> un array fundamental, sino un objeto de la clase 'vector<unsigned char>'.
>
>
> Espero haber aclarado las dudas.
>
> Steven
>
>
> _______________________________________________
> Lista de correo Cconclase Cconclase en listas.conclase.net
> http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
>




Más información sobre la lista de distribución Cconclase