Autor
|
Tema: ¿Es normal hacer este tipo de conversiones de punteros void? (Leído 8,156 veces)
|
D4RIO
Desconectado
Mensajes: 1.004
U N I X
|
Obviamente, debes conocer las diferencias de tamaños para decidir si una union es buena idea o no, y saber si realmente necesitas ese almacenamiento. En ESTA situación, cualquier uso de uniones es DISPARATADO ¿Porqué? Porque cuando aún no sabes si es un médico o un paciente, usas el flag para tratarlo. Entonces ¿realmente necesitas almacenar las estructuras en un espacio de memoria común? Sin importar el tipo, puedes tener dos funciónes diferentes, con lo que la función que hace de dispatcher, no tiene que hacer más que pasar el puntero a quien le corresponda... que me parece mucho más razonable , y si quieres probar si es NULL, lo haces al principio, cosa que te quedaría como: void funcion_dispatcher(void *puntero, tipo_dispatcher flag) { if (!puntero) muere("funcion_dispatcher: puntero nulo!"); switch (flag) { case esMedico: funcionMedico((struct medico*)puntero); break; case esPaciente: funcionPaciente((struct paciente*)puntero); break; } }
O lo que me parece más visible/lindo: void funcion_dispatcher(void *puntero, tipo_dispatcher flag) { if (!puntero) muere("funcion_dispatcher: puntero nulo!"); if (flag == esMedico) funcionMedico((struct medico*)puntero); if (flag == esPaciente) funcionPaciente((struct paciente*)puntero); }
|
|
|
En línea
|
|
|
|
pucheto
Desconectado
Mensajes: 215
|
Obviamente, debes conocer las diferencias de tamaños para decidir si una union es buena idea o no, y saber si realmente necesitas ese almacenamiento. En ESTA situación, cualquier uso de uniones es DISPARATADO Estoy usando una union de punteros, no de structs... todos los punteros ocupan lo mismo, no hay ningun desperdicio de espacio (al menos q sean near, far etc, pero eso ya depende mucho del sistema y es raro encontrarlo en la programacion en modo usuario). ¿Porqué? Porque cuando aún no sabes si es un médico o un paciente, usas el flag para tratarlo. Entonces ¿realmente necesitas almacenar las estructuras en un espacio de memoria común? Sin importar el tipo, puedes tener dos funciónes diferentes, con lo que la función que hace de dispatcher, no tiene que hacer más que pasar el puntero a quien le corresponda... que me parece mucho más razonable , y si quieres probar si es NULL, lo haces al principio, cosa que te quedaría como.... Guardo el flag, con la union de punteros pq estan asociados, estan muy relacionados... Como estan tan relacionados, los pongo en el mismo struct...
|
|
« Última modificación: 19 Mayo 2011, 17:17 pm por pucheto »
|
En línea
|
|
|
|
D4RIO
Desconectado
Mensajes: 1.004
U N I X
|
Estoy usando una union de punteros, no de structs... todos los punteros ocupan lo mismo, no hay ningun desperdicio de espacio (al menos q sean near, far etc, pero eso ya depende mucho del sistema y es raro encontrarlo en la programacion en modo usuario). Guardo el flag, con la union de punteros pq estan asociados, estan muy relacionados... Como estan tan relacionados, los pongo en el mismo struct...
No había visto lo de los punteros. Pero no quita lo que decía, porque usar un "union" donde siempre se usará un puntero, y acceder luego a sus miembros es a fin de cuentas... un casteo. Y si vamos a hacer un casteo es mejor ser explícitos. Por otro lado, no están más relacionados de lo que significa pasar por un mismo dispatcher, porque al final serán tratados por funciónes diferentes. Como al fin y al cabo, usas el union para "castear" el puntero contenido en ese espacio de memoria (el union)... switch(p.flag){ case f_medico: //lo manejo como medico handleMedico(m.data.m); break; case f_paciente: //lo manejo como paciente handlePaciente(m.data.p); break; }
...entonces resulta más legible ir al grano con un cast. A demás, al usar esta forma tienes dos problemas a tener en cuenta: 1 - Necesitas una variable extra en la pila local de la función... solo a fin de alojar el puntero que te llega por parámetro, y para enviarlo a otra función. Es innecesario. 2 - Si declaras desde el main los datos como instancias de la union para evitar las variables locales innecesarias, pierdes la posibilidad de tener flujos donde se manejen solo pacientes, o solo médicos (en el ejemplo), sin pasar previamente por un dispatcher. Si los dispatchers son siempre necesarios, es porque tienes dos flujos separados. Seguramente perderás más de dos bytes haciendo dispatchers para cada flujo, y es la diferencia entre crear una instancia de cada tipo, y una union. Si se desea castear un puntero, entonces se usa un cast, solo por mantener el código simple. Saludos
|
|
|
En línea
|
|
|
|
pucheto
Desconectado
Mensajes: 215
|
1 - Necesitas una variable extra en la pila local de la función... solo a fin de alojar el puntero que te llega por parámetro, y para enviarlo a otra función. Es innecesario.
Una cosa que no veo aca, hagas como hagas, si o si vas a tener que pasarle el puntero a la otra funci\'on. No veo donde esta el problema. En tu codigo tambien tenes que pasar el puntero a una funcion. 2 - Si declaras desde el main los datos como instancias de la union para evitar las variables locales innecesarias, pierdes la posibilidad de tener flujos donde se manejen solo pacientes, o solo médicos (en el ejemplo), sin pasar previamente por un dispatcher. Si los dispatchers son siempre necesarios, es porque tienes dos flujos separados. Seguramente perderás más de dos bytes haciendo dispatchers para cada flujo, y es la diferencia entre crear una instancia de cada tipo, y una union.
Si se desea castear un puntero, entonces se usa un cast, solo por mantener el código simple.
Saludos
Tampoco veo pq se pierde la posibilidad de tener secciones donde solo se manejan solo medicos o solo pacientes. Si podes pone un ejemplo donde se vea mejor.
|
|
|
En línea
|
|
|
|
samur88
Desconectado
Mensajes: 125
|
Una cosa, que me he liado, entonces que sería mas optimo hacer el cast directamente o hacer lo que propone pucheto mediante uniones y estructuras.
Un saludo y gracias por las respuestas.
|
|
|
En línea
|
|
|
|
D4RIO
Desconectado
Mensajes: 1.004
U N I X
|
El cast directamtnte es mejor. Una cosa que no veo aca, hagas como hagas, si o si vas a tener que pasarle el puntero a la otra funci\'on. No veo donde esta el problema. En tu codigo tambien tenes que pasar el puntero a una funcion.
No fue lo que expuse. La diferencia, aclaro, es que necesitas una variable local para usar la union. Tampoco veo pq se pierde la posibilidad de tener secciones donde solo se manejan solo medicos o solo pacientes.
Si podes pone un ejemplo donde se vea mejor.
Este sería el otro caso. Si no usas una variable local, pasas las uniones desde que las creas... probablemente desde el main. Entonces, si una función o grupo de funciones trabajan con "struct paciente", necesitas una funcion intermediaria (un dispatcher), que les pase el puntero. Eso significa una funcion para adaptar a cada flujo que use solo una estructura, cosa que no pasaría si las estructuras fueran siempre diferentes. Solo los flujos que aceptan ambos tipos necesitan el dispatcher. Saludos
|
|
|
En línea
|
|
|
|
Littlehorse
All the world's a stage
Moderador
Desconectado
Mensajes: 2.714
Nie Dam Sie
|
Dependiendo el problema depende que solución es mas aceptable, y esto ultimo siempre va a ser subjetivo. Personalmente para este caso en particular me parece mas correcta la idea de Pucheto que hacer un cast directo. Tal vez las ventajas del planteo de Pucheto no son tan visibles en 10 lineas pero se notarían si tenes que ponerte al día en un proyecto relativamente extenso y encima mantenerlo, aunque esto por supuesto depende de cada uno.
Saludos
|
|
« Última modificación: 19 Mayo 2011, 23:54 pm por Littlehorse »
|
En línea
|
An expert is a man who has made all the mistakes which can be made, in a very narrow field.
|
|
|
pucheto
Desconectado
Mensajes: 215
|
El cast directamtnte es mejor.
No fue lo que expuse. La diferencia, aclaro, es que necesitas una variable local para usar la union. Este sería el otro caso. Si no usas una variable local, pasas las uniones desde que las creas... probablemente desde el main. Entonces, si una función o grupo de funciones trabajan con "struct paciente", necesitas una funcion intermediaria (un dispatcher), que les pase el puntero. Eso significa una funcion para adaptar a cada flujo que use solo una estructura, cosa que no pasaría si las estructuras fueran siempre diferentes. Solo los flujos que aceptan ambos tipos necesitan el dispatcher.
Saludos
Del 1er punto sigo sin ver que variable local uso... Del punto 2, si una funcion trabaja con un paciente solamente, le paso el puntero al paciente, no toda el struct con el flag... el struct con el flag solamente lo uso cuando tenga q manejar de manera generica a medicos y pacientes por igual, y tal vez aplicarle alguna funcion generica que necesite tratarlos de maneras distintas. Depende mucho del contexto de uso todo esto.
|
|
|
En línea
|
|
|
|
D4RIO
Desconectado
Mensajes: 1.004
U N I X
|
Esto ya es un mareo. A ver: Dependiendo el problema depende que solución es mas aceptable, y esto ultimo siempre va a ser subjetivo. Personalmente para este caso en particular me parece mas correcta la idea de Pucheto que hacer un cast directo. Tal vez las ventajas del planteo de Pucheto no son tan visibles en 10 lineas pero se notarían si tenes que ponerte al día en un proyecto relativamente extenso y encima mantenerlo, aunque esto por supuesto depende de cada uno.
Supongo que será por lo relativo, pero yo, siendo nuevo en un proyecto, preferiría mil veces encontrar esto: if (flag == esMedico) funcionMedico((struct medico*)puntero); if (flag == esPaciente) funcionPaciente((struct paciente*)puntero);
que es explícito en lo que hace, y no esto: case f_medico: //lo manejo como medico handleMedico(m.data.m); break; case f_paciente: //lo manejo como paciente handlePaciente(m.data.p); break;
que es como... poco claro, a mi parecer. Del 1er punto sigo sin ver que variable local uso...
Si no lo entiendo mal, recibes un puntero en la función, y haces algo como: void funcion(void *punt ...) { personaHospital p = (personaHospital) *punt; /* algo asi, que requiere una variable local p, o un puntero */ switch(p.flag){ case f_medico: //lo manejo como medico handleMedico(m.data.m); break; case f_paciente: //lo manejo como paciente handlePaciente(m.data.p); break; } }
Que no era necesaria sin la union... Del punto 2, si una funcion trabaja con un paciente solamente, le paso el puntero al paciente, no toda el struct con el flag... el struct con el flag solamente lo uso cuando tenga q manejar de manera generica a medicos y pacientes por igual, y tal vez aplicarle alguna funcion generica que necesite tratarlos de maneras distintas. Depende mucho del contexto de uso todo esto.
Creo que nunca se manejarían "por igual"... si tuvieran miembros en común que se manejen por igual, entonces metería algo como herencia. Una estructura compartida entre ambos al inicio de la estructura de cada uno. Y así los despachos con un único puntero siguen siendo válidos, aunque en realidad habrá código compartido tanto como código para cada implementación. Estamos tratando de dar solución a ningún problema, creo que eso es lo más confuso Muestrame el código que pondrías para darme una mejor idea de tu idea. Saludos
|
|
|
En línea
|
|
|
|
pucheto
Desconectado
Mensajes: 215
|
Ta, estabamos pensando distinto el problema... Yo suponia que el tipo 'personaHospital' venia ya de arriba, pq lo crea una funcion o algo asi... mi funcion con la version que yo proponia era tomar directamente el struct personaHospital, y no un puntero para despues convertirlo.
Mi idea era hacerlo algo similar a herencia.
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Ayuda para hacer firmas d este tipo
Diseño Gráfico
|
bautistasbr
|
2
|
2,063
|
8 Agosto 2006, 13:42 pm
por Ozonox
|
|
|
¿Como hacer este tipo de animacion?
Diseño Gráfico
|
NHME
|
5
|
3,609
|
12 Noviembre 2007, 16:17 pm
por Azielito
|
|
|
como hacer firmas de este tipo
Diseño Gráfico
|
darkvidhack
|
2
|
3,250
|
1 Septiembre 2009, 17:23 pm
por darkvidhack
|
|
|
¿Cómo hacer este tipo de htaccess para urls?
Desarrollo Web
|
robe007
|
0
|
1,326
|
27 Abril 2012, 21:41 pm
por robe007
|
|
|
como hacer este tipo de paginas??
Desarrollo Web
|
Elmonky
|
3
|
2,424
|
18 Junio 2012, 00:14 am
por darkvidhack
|
|