Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





C++ y POO

Iniciado por sukhur, 05 de Enero de 2007, 10:12:24 AM

« anterior - próximo »

fiero

Cita de: "shephiroth"Respecto q todo hereda de CWnd en vez de Control, querido compañero, podrías comprobar CWnd de que hereda???

Sí, CWnd deriva de CCmdTarget que a su vez deriva de CObject, clase base de toda la MFC. Por cierto, estas dos clases con una funcionalidad muy básica que no tiene nada que ver con controles. Lo puedes ver aquí http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_mfc_hierarchy_chart.asp

Yo no he dicho que todo derive de CWnd, he dicho que todos los controles que se usan en dialogos deriban de CWnd, y esta clase no tiene implementadas todas las funciones de todos los controles. Además no existe ninguna clase "Control" como tú decías, que tenga implementadas todas las funcionalidades de todos los controles.

un saludo
www.videopanoramas.com Videopanoramas 3D player

Fran

Cita de: "tamat"
CitarThe two most common ways to eliminate RTTI are to add virtual functions higher in the hierarchy and to hold onto a derived class interface by not promoting the derived class type to its base class type. For example, if you can replace RTTI with virtual function calls by modifying a base class, that's usually a better way to go.

En otras palabras, usando un metodo virtual como getType().

Yo no he leido tanto como vosotros pero he visto mucho codigo y en TODOS he visto algun tipo de getType() (TinyXML lo hace para saber el tipo de elemento, la libreria para abrir FBX o usa para saber el tipo de objeto de la escena, etc).

¿?

Las dos formas más comunes de eliminar RTTI (xq no da lugar a pensar q no hay q quitarlo) son añadir funciones virtuales en un nivel más alto de jerarquia (es decir en las clases base) sin promover el tipo de la clase a su clase base (esto sobra. Es de cajon).  Por ejemplo, reemplazar RTTT con llamadas a funciones virtuales modificadno la clase base (lo q yo hice al principio del hilo) es usualmente la mejor manera de actuar o de hacerlo.

No sé que traducción has hecho

Por cierto. Y esto no es con ánimo de ofender ni con ningun animo de aleccionar ni nada por el estilo.  Lee mucho de buenos autores xq el ver mucho código si quien lo escribe no tiene la base suficiente es más perjudicial que otra cosa. Adquieres las malas costumbres de los demás. Eso te da bastante criterio para luego saber separar el buen código del mal código. Hay muchos códigos q funcionan, pero (ES MI OPINION) no quiere decir q sean buenos códigos.

shephiroth

Bueno, parece que sigo con mis cagadas, menuda semana llevo. Tienes razon, en el MFC CWind es la clase base de ventanas.  He estado buscando la de ATL pero no la he encontrado (si alguien tiene enlace, estaría muy agradecido xDD).

Referente a la clase control, System::Windows::Forms::Control.

SALUDOS ^^

Vicente

Cita de: "shephiroth"Vicente, solo por curiosidad, te suena de algo los "EVENTOS"??? Deja de ser tan pesado con tu codigo de cambiar el selecteditem. Para que sepas eso lleva años solucionado, añadiendo un evento, y cuando en el codigo interno cambias de seleccion comprueba si has añadido dicho evento y llama a la funcion miembro que hayas creado para recibir dicho evento.

Yo debo escribir muy mal la verdad... A ver, primero, SI se lo que es un evento en .NET (por si acaso, pero me hace gracia que me lo preguntes).

Segundo, te pego lo que puse:

"- si tienes un panel con 2 botones y un listbox, y quieres acceder al elemento seleccionado del listbox, crees que funciona el iterar sobre todos los controles contenidos en el panel preguntando por su selecteditem? O que te tocará preguntar por su tipo para ver si es un listbox?"

Aquí nadie habla de cambiar el SelectedItem, hablo de ser capaz de ejecutar la propiedad SelectedItem. Y la respuesta es que es imposible que ejecutes la propiedad SelectedItem del ListBox porque Control no la tiene. Ni virtual vacia, ni nada de nada. No la tiene, porque no debería tenerla, por mucho que una clase que herede de ella la pudiera tener. Control tiene lo mínimo que debe tener, no un porrón de métodos virtuales vacios sin pies ni cabeza.

Os he explicado porque a veces aparecen métodos virtuales vacios en las librerías de clases como Java o .NET. Es un problema de compatibilidad hacia atrás, no de que sea mejor diseñar cosas (porque vamos, si eso fuera así pues nada, que se pongan todos los métodos como virtuales vacios en Object y a correr). Quizás sea problema de haber mezclado C++ y Java/.NET ya que en C++ RTTI es algo no sé, marginal (o esa impresión me da) mientras que en Java/.NET la reflexion es una herramienta de primer orden.

Fran:

En el primer caso que comenta (lo que has puesto en negrita) dice un "usually" bastante majo ;)

Y luego podrías haber quoteado esto:

"C++ has no Object class like Java or C#. So instead of having, for example, a container of base class pointers, you can have three containers, one for each different type of derived class you're dealing with. Then you'll never lose the type information and you'll never have to do the downcast, so you don't need RTTI. "

Está claro que si tienes tres contenedores cada uno que tiene su propio tipo (con templates) no hay problemas. El problema es que estás mezclando por la clase base (Vehiculo en el ejemplo inicial, Control en el ejemplo de las ventanas, y Object en el caso general de Java o .NET), con lo cual necesitas alguna forma de saber el tipo (GetType()). Supongo que ese artículo es bastante viejo porque se refiere a los contenedores de Java y .NET cuando aún no tenian genericos (<T>) mientras que C++ si tenía templates, y por eso aparecía el problema del downcast.

Si tienes el downcast, nada te salva del GetType, y eso es lo que estamos hablando aquí, y lo que has quoteado tu mismo ;)

Un saludo!

Vicente

Fran

No. Que yo sepa aquí hemos estado hablando de si en C++ es mejor hacer o  usar RTTI o implementar los métodos virtuales hacia arriba. Y ningun autor deja lugar a dudas. Simplemente y sin liar la pelota. Y si, usually = lo normal. Lo otro es lo anormal.


Sigues intentando vender las bondades del RTTI o getType contra la teoria tradicional de OOP y a mi desde luego sigues sin convencerme. Buscame un autor de prestigio que diga que RTTI es mejor, mas adecuado para cosas como hacer un GUI o incluso las motos, y quizás me convenzas. Pero yo por ahora, y por mi experiencia me decanto mas por esa solucion, junto con C#, Delphi, Java, incluso el enlace a la jerarquia de clases de M$ en la que aun a sabiendas de que hay muchos métodos q van a devolver "burradas" o nil si se derivan de un clase madre de la q se quieren heredar 4 cosas, lo hacen


(Y q conste q tengo claro q para algunas cosas si es util y lo llevo diciendo todo el post)

Diferencial

Fran como resolverias el problema que ha planteado Vicente. (Java) Por ejemplo yo tengo una lista y varios botones en mi interfaz. Cada uno tiene asignado su metodo addActionCommand() en la misma clase que implementa ActionListener. Dentro del metodo actionPerformed() como sabes tu que objeto ha provocado el evento??

Por cierto se parece bastante al problema que se planteo desde el principio donde se quiere meter todo dentro del mismo vector.
PARA TENER COSAS QUE NUNCA HAS TENIDO, TENDRÁS QUE HACER COSAS QUE NUNCA HAS HECHO.

Jare

1 - Extender las clases base con métodos virtuales vacíos.
2 - Llamar a getType() en el código que usa esas clases.
3 - Acompañar a un contenedor polimórfico de contenedores para cada tipo concreto.

La primera es la solución "por defecto" siempre que podamos hacerlo (podamos modificar las clases con las que estamos trabajando) y no se nos vaya de madre.

La segunda es la solución habitual cuando no podemos (o no queremos) incluir la funcionalidad que estamos programando dentro de esas clases.

La tercera suele aplicarse para optimizar, o cuando no queremos abusar de ninguna de las otras dos.

Hacer cualquier cosa de esas por norma es una marranada, hacerlo cuando resulta apropiado es perfectamente válido. Menos religión y más sentido común! :P

burb


fiero

www.videopanoramas.com Videopanoramas 3D player

FANatiko

Hombre, usar RTTI a lo bruto no es buena idea... sobretodo porque ALGUNOS compiladores no tienen soporte de RTTI completo y simplemente solucionan casos sencillos (por contra, el Visual C++, p.ej, puede resolver cosas muy complejas, con herencias multiples y demas).

En mi opinión, si puedes buscar una forma de no tener que depender de ella, pues tanto mejor. Pero ojo, en esto, como dice Jare, tampoco hay reglas que sirvan siempre... aunque quizas no sea buena practica diseñar pensando en usar RTTI, sino que, cuando te lo encuentras, la usas y punto.

Yo prefiero el metodo de RTTI a lo de los metodos vacios, pero es simplemente una elección personal... es mas, consultrare mañana el Effective C++ 3a edición a ver que dice de RTTI...

Fran

Cita de: "Diferencial"Fran como resolverias el problema que ha planteado Vicente. (Java) Por ejemplo yo tengo una lista y varios botones en mi interfaz. Cada uno tiene asignado su metodo addActionCommand() en la misma clase que implementa ActionListener. Dentro del metodo actionPerformed() como sabes tu que objeto ha provocado el evento??

Por cierto se parece bastante al problema que se planteo desde el principio donde se quiere meter todo dentro del mismo vector.

No entiendo la pregunta. Xq q yo sepa cada boton puede tener su propio Listener y la JList tb. Asi q explicate mejor. Pero vamos, hay una cosa que ha dicho Jare en la q estoy completamente de acuerdo. Para cada cosa uso lo que sé q da mejor resultado. Partiendo del hecho de q el mejor código es el q no existe y de que si algo me limita y no me deja meter funcionalidad nueva que se le haya olvidado al puñetero cliente no me gusta, para las lavadoras me reafirmo en que seguiria en la misma historia. Xq si por ejemplo se le ha olvidado que ... ah!!!! además hay bicicletas, bastaria con añadir una nueva clase y todo lo demás funcionaría o que de pronto se le ocurriera que la moto si tiene x propiedad con hacerle un override valdría. No haría faltra nada más. Esa clase de ventajas es la q me inclina a usar en ese tipoi de casos eso. Aunq  desde luego mis clases hijas se parecen mas a sus padres. Pero vamos. Lo q si no adoptaria es getType ni RTTI xq p.e. si quieres meter una nueva clase tendrías q ir a todos los sitios donde uses las propiedades y meter nuevos cases, etc,etc. A cada cosa lo q menos te haga programar y la OOP bien usada te hace programar poco y ser muy flexible.

Por cierto. Me da q el ejemplo este q ya me explicaras no se parece en nada. Pero lo podemos derivar a él y al inicial de una clase base y yasta. Los casamos y tienes razon q se parecen.

zupervaca

En mi opinion creo que se esta debatiendo algo absurdo, ya que aunque yo defiendo el tipo de funciones getType como una funcionalidad extra, en toda la libreria multiplataforma que monte no la uso, el motivo es muy sencillo, no me he encontrado ningun caso en el que me haga falta, es mas en las propiedades del visual studio tengo desactivado el RTTI.
El otro dia pensando como meter ogl 1.1 pense en hacer funciones virtuales vacias que retornen NULL y en debug produzcan una ruptura del programa cuando se intenta crear por ejemplo un pixel o vertex shader ya que en la version de ogl 1.1 no se pueden crear (el motivo es para poder renderizar igualmente sprites 2d con la clase sprite desde ogl 1.1), con lo que aunque defiendo el getType siempre lo intento usar lo menos posible, no obstante creo que para el problema que indica el primer post del hilo no queda mas remedio, ya que mete todo en un mismo vector, otra posibilidad al getType para este problema es crear una funcion virtual en la clase base que permita obtener propiedades mediante un string o un identificador numerico (algo asi como la clasica funcion de mensajes que se usaba en c), como veis hay mas soluciones, no existe una mejor o peor, es solo cuestion de como se programe o nos guste programar o nos digan como debemos hacerlo :wink:
Creo que el caso que se expone aqui es algo imposible de encontrarse (por lo menos en la vida laboral, en la de estudiante puede), referente a los GUI normalmente se soluciona todo mediante eventos, el evento lo recibe el propio control, con lo que en el evento de ese control ya se sabe que tipo de control es y sabemos lo que queremos hacer.

Fran

Cita de: "zupervaca"En mi opinion creo que se esta debatiendo algo absurdo, ya que aunque yo defiendo el tipo de funciones getType como una funcionalidad extra, en toda la libreria multiplataforma que monte no la uso, el motivo es muy sencillo, no me he encontrado ningun caso en el que me haga falta, es mas en las propiedades del visual studio tengo desactivado el RTTI.
El otro dia pensando como meter ogl 1.1 pense en hacer funciones virtuales vacias que retornen NULL y en debug produzcan una ruptura del programa cuando se intenta crear por ejemplo un pixel o vertex shader ya que en la version de ogl 1.1 no se pueden crear (el motivo es para poder renderizar igualmente sprites 2d con la clase sprite desde ogl 1.1), con lo que aunque defiendo el getType siempre lo intento usar lo menos posible, no obstante creo que para el problema que indica el primer post del hilo no queda mas remedio, ya que mete todo en un mismo vector, otra posibilidad al getType para este problema es crear una funcion virtual en la clase base que permita obtener propiedades mediante un string o un identificador numerico (algo asi como la clasica funcion de mensajes que se usaba en c), como veis hay mas soluciones, no existe una mejor o peor, es solo cuestion de como se programe o nos guste programar o nos digan como debemos hacerlo :wink:
Creo que el caso que se expone aqui es algo imposible de encontrarse, referente a los GUI normalmente se soluciona todo mediante eventos, el evento lo recibe el propio control, con lo que en el evento de ese control ya se sabe que tipo de control es y sabemos lo que queremos hacer.

Sabias palabras. Yo soy de los de virtual. No me gusta siempre que pueda usar RTTI. De hecho solo me ha hecho falta cuando he diseñado mal la jerarquia de clases y tenia demasiada prisa para ponerme a reestructurar lo. El debate surgio en un principio xq alguen me dijo q eso no era OOP y q RTTI o getType si. Y he demostrado con citas de varios autores que es al contrario. Pero siempre he dicho q hay casos en q no qda mas c....s. En cuanto a la pregunta ya he dicho q no la entiendo xq como tu bien dices y yo tb he reseñado arriba en todos los GUIs que yo conozco incluyendo Java cada control tiene su propio actionListener o evento o como quieras llamarlo. Asi q o no entiendo la pregunta o la pregunta no está hecha bien o .....

shephiroth

Cita de: "Vicente""- si tienes un panel con 2 botones y un listbox, y quieres acceder al elemento seleccionado del listbox, crees que funciona el iterar sobre todos los controles contenidos en el panel preguntando por su selecteditem? O que te tocará preguntar por su tipo para ver si es un listbox?"

Este ejemplo tal cual esta expuesto me parece mal planteado. Si tienes un panel con varios botones y un listbox y quieres acceder al listbox, pues accedes directamente. Si tienes todos los controles vectorizados segun la clase base CWnd seguro que tienes necesidades de cosas raras (o getType como quieras), pero creo q eso se debe mas a una mala planificacion de tu clase que a una obligacion heredada del uso de POO. Pero si sigues pensando lo mismo, ponme un caso real, que quedandonos en medias pintas es normal que no nos entendamos.

Cita de: "Diferencial"Fran como resolverias el problema que ha planteado Vicente. (Java) Por ejemplo yo tengo una lista y varios botones en mi interfaz. Cada uno tiene asignado su metodo addActionCommand() en la misma clase que implementa ActionListener. Dentro del metodo actionPerformed() como sabes tu que objeto ha provocado el evento??

Por cierto se parece bastante al problema que se planteo desde el principio donde se quiere meter todo dentro del mismo vector.
Por fin, un ejemplo claro. Me aventuro mucho pq en java por lo que leo cambian las cosas mucho respecto de c, pero intentaré.

Que diferentes botones creen un evento y recaiga sobre una funcion comun para ambos me parece una locura. Yo cuando hago formularios los botones solo comparten funcion si no se hace referenia ninguna al control que lanzo el evento. Pero aun asi, si por alguna razon lo necesitase, no se si en java existe pero en los winforms existe una propiedad (heredada de Control) llamada FOCO, el cual lo tiene (salvo que el programador lo cambie a mano) el control que lanza el evento.

Aunque como digo mas arriba, me parece una mala programacion el que diferentes controles tengan eventos que apunten a una funcion comun la cual necesita diferenciar que control lanzo el evento.

zupervaca

Para solucionar el caso que indicais en el que una funcion puede ser llamada desde diferentes controles es que en los eventos de cada control se llama a esa funcion comun, la funcion solo puede tener cosas en comun que tienen los controles, los demas cambios se producen en los eventos de cada control.






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.