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"Iconos, botones, combobox y todos los controles de un formulario no derivan de Window, derivan de Control.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_mfc_hierarchy_chart.asp

Todos los controles, vistas, dialogos, etc, derivan de la clase ventana genérica CWnd, o si se usa el API de Windows a pelo, identificadores HWND.

Me extraña mucho que todas las clases base de VCL de Delphi incluyan todos los metodos de todas sus posibles derivadas, pero bueno, yo no he leido a ese señor.

un saludo
www.videopanoramas.com Videopanoramas 3D player

Fran

Ya. Pues por ejemplo y ya q sacas el tema de MS. Crees q un CButton devolverá algo si llamas a su metodo GetMenu?  o un checkbox? Y sin embargo su clase padre (CWnd) los tiene implementados (mirate el enlace que has puesto).........  Por cierto. Haces muy mal no leyendo a Heiljsberg. Dado q fué quien diseño Delphi y C# creo q aprenderías como cualquiera (yo incluido) mucho

De la ayuda de Microsoft que has puesto tu mismo

GetMenu

Return Value

Identifies the menu. The value is NULL if CWnd has no menu. The return value is undefined if CWnd is a child window.

The returned pointer may be temporary and should not be stored for later use.
Remarks

This function should not be used for child windows because they do not have a menu.

Ostras!!!!! Lo q ha dicho. Ha implementado cosas en la clase base que en las hijas no devuelve nada.... SACRILEGIO. Con lo bien que qdaria un RTTI

Vicente

Cita de: "Fran"os recomiendo leais una gran obra (de alguien q a día de hoy tiene en su haber dos grandes productos : Anders Helsberg  (Delphi y C# (es el arquitecto jefe))

Pues Helsberg no ha repetido la jugada en el framework de .NET: la clase control no tiene todos los métodos posibles de todos los controles que heredan de ella como métodos virtuales vacios... Si recibes un control generico (por ejemplo de la lista de controles que contiene un panel), o haces algo como el if (es de este tipo) o vas apañao...

Un saludo!

Vicente

Fran

Cita de: "Vicente"
Cita de: "Fran"os recomiendo leais una gran obra (de alguien q a día de hoy tiene en su haber dos grandes productos : Anders Helsberg  (Delphi y C# (es el arquitecto jefe))

Pues Helsberg no ha repetido la jugada en el framework de .NET: la clase control no tiene todos los métodos posibles de todos los controles que heredan de ella como métodos virtuales vacios... Si recibes un control generico (por ejemplo de la lista de controles que contiene un panel), o haces algo como el if (es de este tipo) o vas apañao...

Un saludo!

Vicente

Lee mi anterior mensaje. Estamos tratando de si es ortodoxo o no meter metodos virtuales aunq devuelvan cosas como cero o cosas ( a vuestro modo de entender incongruentes).  Delphi lo tiene. Java lo tiene. La plataforma NET lo tiene , etc, etc. Luego cuando las principales plataformas OOP lo tienen tiene q ser bastante ortodoxo . Vamos para mi y para los autores de herramientas como esas (y otras que ya he referenciado) las ventajas son  claras. Cuanto mas grande es el proyecto y mas escalable quieres que sea, las ventajas lo son mucho mas. Y es q la verdad es q creo q si no lo veis hay poco mas q decir. Yo me enfrento en el dia a dia a cosas como tener q implementar funcionalidad que en 5-10 dias tiene q estar probada y en la calle en un programa de 800.000 lineas. Si tuviera q estar incluyendo con RTTI una subclase nueva en todo el programa... me cortaba las wenas. Si lo q hago es lo del camion o cosas en las q no hay plazo puedo entender q lo veais asi.

Vicente

A ver, que yo sepa Helsberg no diseñó la WinAPI... Y que yo sepa RTTI entró bastante tarde en C++, con lo cual puede (que no lo sé a ciencia cierta), que ese código se escribiera antes de que se pudiera usar RTTI en C++. Hasta donde yo tengo entendido en C++ el tema de la reflexión es mucho menos usado que en Java o .NET.

Ahora volvamos a cosas que ha diseñado Helsberg como .NET, que traen soporte nativo de reflexión (que para lo mala que es se usa que no veas).

- 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?

- si la reflexion es tan mala (RTTI), porque en .NET y Java GetType viene de serie en la clase object? (con lo cual todo el tiene ese método tan malo).

Un saludo!

Vicente

Fran

Mirad:

http://developers.sun.com/learning/javaoneonline/2005/coreplatform/TS-3268.pdf

Mito 3:

Uso de RTTI contra virtual

Leeroslo. Creo q hemos acabado.

Myth 3: use Run-Time Type Info
● int per object, passed into Base constructor
● Turns OO Java code into C code

Es decir. RTTI = C--, Virtual =OOP

Lo ortodoxo es usar esto, no RTTI aunque a veces tengas q usarlo

Saludos

Vicente

Por cierto, las razones que citas por las que .NET y Java tienen métodos virtuales vacios son diferentes a las de este caso.

La razón de meter un método virtual vacio en una clase abstracta de una libreria es porque:

- si lo metes en una interfaz, te cargas todo el código que use esa interfaz porque ya no la implementan correctamente.

- si lo metes abstracto en la clase abstracta te pasa lo mismo.

Con lo cual cuando estás sacando versiones de librerías, si te ves obligado a meter un método nuevo en las clases base, la unica manera que tienes de que no rompa el código que ya hay desplegado con las clases antiguas es meterlo ya implementado pero que no haga nada.

Un saludo!

Vicente

Fran

Cita de: "Vicente"Por cierto, las razones que citas por las que .NET y Java tienen métodos virtuales vacios son diferentes a las de este caso.

La razón de meter un método virtual vacio en una clase abstracta de una libreria es porque:

- si lo metes en una interfaz, te cargas todo el código que use esa interfaz porque ya no la implementan correctamente.


si lo metes abstracto en la clase abstracta te pasa lo mismo.

Con lo cual cuando estás sacando versiones de librerías, si te ves obligado a meter un método nuevo en las clases base, la unica manera que tienes de que no rompa el código que ya hay desplegado con las clases antiguas es meterlo ya implementado pero que no haga nada.

Un saludo!

Vicente

Para tu info por ejemplo, una interfaz en Java no tiene implementacion. Que si , q vale. Pero digais lo q digais. RTTI = C-- . Vamos contraorientacion a objetos. Aunq a veces sea necesaria. Y no lo digo yo ya. Leed y lo vereis.

Vicente

Claro, por eso rompes el código que ya esté desplegado con esa interfaz, porque las clases que implementen la interfaz no compilan porque tienen que implementar ese nuevo método que has añadido ;)

Un saludo!

Vicente

Fran

Cita de: "Vicente"Claro, por eso rompes el código que ya esté desplegado con esa interfaz, porque las clases que implementen la interfaz no compilan porque tienen que implementar ese nuevo método que has añadido ;)

Un saludo!

Vicente

Sinceramente no estoy siguiendo tu ejemplo. Simplemente digo y repito q si hay algo poco ortodoxo en toda esta conversación es la RTTI (aunq sigo diciendo q hay veces q es necesaria). Pero eso no es ++. Es --. Simplemente informaos y ya está.

Saludos

Vicente

La verdad es que puede que no me haya explicado muy bien. A ver que lo intento de nuevo.

Mi objetivo era explicar porque a veces las librerías de clases tienen métodos virtuales vacios (algo que yo he dicho que no está bien). Si tu haces una librería de clases (como VCL, JDK, o .NET) que va usar otra persona, normalmente das interfaces y clases abstractas que servirán como base para que el usuario extienda esas librerías (por ejemplo, la clase abstracta Control).

Si después de sacar la versión 1 de tu librería, al sacar la versión 2 te das cuenta de que hace falta un método nuevo, la única forma posible que tienes de añadir ese método sin romper el código de la gente que use tu librería version 1 es añadir un método vacio en una clase base.

- Si añades una declaración de método a una interfaz rompes las clases que usan la interfaz porque tienen que implementar ese nuevo método.

- Si añades un método abstracto en una clase abstracta las clases que la hereden también se rompen porque no implementan el método abstracto (y tendrían que pasar a ser abstractas).

Con lo cual la única solución que te queda es implementarlo vacio para evitar romper el código de terceros que pudiera haber usado tu clase base.

Por eso aparecen métodos "sin implementación" en clases base, porque son necesarios cuando van apareciendo versiones para no romper la compatibilidad hacia atrás, pero no porque sea un buen mecanismo de diseño cuando se diseña al principio la librería. Mirate la clase System.Windows.Form.Control de .NET, lo mismo tiene algún método vacio (que ni idea) por algún caso especial como el que antes te he comentado, pero lo que no tiene es un método vacio para todas las funcionalidades de las clases que derivan de ella, porque sería una locura absoluta.

Si quieres hacer lo del panel que te puse antes y que no respondiste, la única forma es preguntar si el control es un listbox antes de ejecutar el método (o andar cazando excepciones :p). Y eso no es malo, es que es así y no hay otra manera de hacerlo.

Un saludo!

Vicente

fiero

Pero, olvidais algo... YO quiero tener razón!!!   :)
www.videopanoramas.com Videopanoramas 3D player

Fran

http://www.artima.com/intv/constP.html


De Scott Meyers (Guru C++ al nivel de S...UP o como se ponga)

When to Use RTTI

Bill Venners: You said in the first edition of Effective C++:

   Fortunately, C++ provides no way to determine at runtime the actual type of object a pointer points to, and let me assure you this is no accident. In fact, runtime type inquiry (RTTI) was explicitly omitted from the language to prevent abuses such as this.

Doesn't C++ have RTTI now?

Scott Meyers: Yes.

Bill Venners: When is it appropriate to use RTTI?

Scott Meyers: Let me give you some history on why the committee added RTTI to the C++ language. This is one of those cases where the consumers won. At the time, every non-trivial class library being written was rolling its own RTTI, without exception. Every major class library used at the time, including MFC (Microsoft Foundation Classes) and NIHCL (National Institute of Health Class Library), had RTTI of some form or another. So the committee just said, "Rather than have N different ways to accomplish the same thing, we're going to have a single language mechanism that does the right thing." That's why RTTI was added. It was a simple matter of people wanted it.

Once the committee added RTTI, people started wondering when it was appropriate to use RTTI. All the bad things I wrote about RTTI in the first edition of Effective C++ continue to apply. They're still bad. So you end up with a classic engineering tradeoff. You use RTTI when the alternatives are worse.

The 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. The other approach, eliminating the need to upcast in the first place, is especially appropriate in C++, because C++ has type-safe containers. 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.


Yo, esta vez de verdad, con esto me despido . Xq creo q hay poco más que discutir. Los creadores de C++ te dicen q no lo uses y q intentes usar lo q yo puse al principio aunq suene raro . Los de Java q eso no es OO , etc, etc.. Y yo ademas de lo q ellos digan (q es todo) digo q habiendo programado mucho muchisimo ;) y muchos años, no hace falta q vengan a decirmelo ellos. Mi propia experiencia me dice q es mucho mejor lo q ahi dice y por eso dí la solucion q di a las lavadoras y carros del principio del hilo.

Saludos

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.

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

Voy a ver si consigo encontrar en la documentacion la tabla de herencias. La he visto en mas de una ocasion pero no me acuerdo donde estaba en este momento. Si la encuentro os la pongo.

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).
Por un stratos menos tenso






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.