Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Duda Sobre C++: Multiherencia Y Templates

Iniciado por tamat, 18 de Abril de 2004, 08:27:29 PM

« anterior - próximo »

tamat

 La duda es algo compleja así que trataré de exponerla lo mejor posible pero aviso que requiere ser leida con detenimiento, trata sobre herenciamultiple:

Tengo un template Composite que representa el patron de diseño del mismo nombre. Mediante este patron puedo hacer que cualquier clase tenga un padre y una serie de hijos, esta clase recibe como parametro el tipo de la clase que será padre o hijo y ya está, internamente no tiene ningun misterio.
Utilizo este template porque contantemente topo en mi codigo con que algun elemento tiene un padre y una serie de hijos por lo que viene bien disponer de ella.

Bien, por otra parte tambien ví que algunas clases de mi sistema necesitan poder enviar mensajes, así que pensé que lo mejor sería crear una clase MessageHandler que puede lanzar y recibir mensajes. Esta clase tiene un atributo que dice a quien debe enviarselos, y si no se le asigna nadie pues tira el mensaje a la basura.

Tengo implementada una clase Widget para cada elemento de mi GUI, cada widget contiene dentro una serie de widgets hijo, algo obvio, un widget ventana puede contener dentro un widget boton y un widget texto. Por eso hago que la clase widget herede de Composite, pero como además cada widget puede generar mensajes pues tambien hereda de MessageHandler.

De momento mediante esta jerarquía todo funciona perfectamente, pero el problema viene ahora.
Me gustaría hacer que cuando un widget genera un mensaje y no tiene asociado ningun MessageHandler que lo procese entonces que se lo envie a su padre, así de sencillo, pero claro, MessageHandler no sabe nada de padres e hijos, él no hereda de Composite así que no tiene esa parte.

He pensado - pues hagamos que MessageHandler tambien herede de Composite -, pero exactamente de Composite< qué? >, no puedo hacer que herede de Composite< Widget > porque un MessageHandler no tiene porqué saber de widgets. La solución sería que heredase de Composite< MessageHandler > y en parte sería correcto porque la clase Widget hereda de MessageHandler por lo tanto cuando hago que Widget herede de Composite< Widget > es como si hiciera que heredase de Composite< MessageHandler > pero no es así exactamente.

En resumen, qué puedo ahcer? Si hago que MessageHandler herede de Composite< MessageHandler > el compilador resolverá el problema o se liará y creerá que Composite< Widget > y Composite< MessageHandler > son clases diferentes y por lo tanto me vendrá con errores de ambiguedad al llamar a SetParent ?

Arf, esto del polimorfismo se complica cada vez más...

En fin, gracias por leerlo y espero que este no se convierta en otro thread de dudas sin respuesta de tamat.
Por un stratos menos tenso

ethernet

 si pegas codigo mejor q mejor, es dificil seguirlo si no ves codigo

saludos

tamat

 Lo pensé pero creo que ver el código no ayudará a entender el problema ya que es un problema sobre el funcionalidad, no sobre sintaxis, además estariamos hablando de pastear muchisimo codigo, aunque cortase lo irrelevante. Creo que más o menos está claro, mi pregunta es:

Creerá el compilador que Composer< Widget > es diferente de Composer< MessageHandler > si Widget hereda de Message Handler?  
Por un stratos menos tenso

ethernet

 podrias pegar el patron composite, he mirado implementaciones y no lo asocio con lo q dices tu :)

por otra parte los templates no son iguales si las clases son diferentes aunque hereden unas de otras. Solo tienes q pensar en el sizeof de ellas, puede no ser el mismo. Quizas la implementacion que cree el compilador al final sea igual, habria q mirarlo

un saludo

CoLSoN2

 
CitarEn fin, gracias por leerlo y espero que este no se convierta en otro thread de dudas sin respuesta de tamat.
por otra parte ya míticos XDDDDDDD
No, en serio. No te compliques tanto xD  
Manuel F. Lara
Descargar juegos indie  - blog sobre juegos indie y casual
El Desarrollo Personal.com  - blog sobre productividad, motivación y espíritu emprendedor

pekesan

 Esto, los mensajes no se propagaban hacia arriba en la jerarquía de clases? o me lo acabo de inventar?.


tamat

 Cuando digo 'propagar mensaje hacía arriba' no me refiero a llamar a los metodos de la clase base, sino a llamar a un metodo de otra instancia que es la que contiene a dicha instancia, es el patron composite, que hace que una instancia contenga otras y así recursivamente para generar un arbol.
Por un stratos menos tenso

Juan Mellado

Hola tamat,
tal vez te interese otro patrón de diseño llamado "chain of responsibility" (cadena de responsabilidad), que lo que consigue es que un mensaje se extienda a lo largo de los elementos de una jerarquía.

Lo he estado mirando en el "Design Patterns", y en el apartado de patrones relacionados indica de forma expresa el Composite. Y de hecho, todos los ejemplos son con Widgets.

Un poco de código (copiado, pero no probado):

class MessageHandler
{
public:
   MessageHandler(MessageHandler * s) : m_succesor(s) {}
   virtual void HandleMessage()
   {
     if (m_succesor){
           m_succesor->HandleMessage();
         }
   }
private:
  MessageHandler * m_succesor;
}

Una clase que heredase de Widget (que a su vez heredaría de MessageHandler) sobrecargaría el método HandleMessage (o no), para procesar el mensaje (o no) y/o lo dejaría pasar al siguiente manejador de mensajes de la cadena (o no).

class Widget : public MessageHandler
{
 Widget(Widget * Parent) : MessageHandler(Parent) {...}
...
}
class Button : public Widget
{
 void HandleMessage()
 {
    if (quiero procesarlo){
          ...
         }
   else{
         MessageHandler::HandleMessage();
        }
 }
...
}

La clave está en que la clase MessageHandler no sabe nada de ninguna otra clase que no sea ella misma. Y de esta forma, no sería necesario que la clase MessageHandler supiera nada de Composite.

En google aparecen bastantes enlaces.

Espero te sirva.

Saludos

tamat

 Conozco ese patron, una Chain of Responsability lo que hace es mirar a que clase de la jerarquía de clases de una unica instancia le corresponde procesar un evento, empezando por la que está más abajo y si esta no puede entonces lo envia al metodo de la clase que esté encima en la jerarquía de herencia, repito, una UNICA instancia.

Esto yo ya lo uso para otras muchas cosas en el apartado de widgets, sin eso sería imposible.

Mi problema no está en enviar el mensaje a clases superiores sino a instancias superiores, es lo mismo que comenté en mi anterior post. Yo aquí tengo decenas de instancias, cada una contenida dentro de otra (por contener me refiero a que cada instancia tiene una lista de instancias hijo y un puntero a una instancia padre), eso es el patron composite.

Con esto consigo un arbol jerarquico de clases, de manera que si pido que se renderize el nodo padre este se pintará y mandará pintar a sus hijos, y así recursivamente, con la ventaja de que cada widget se preocupa de su contenido.

Si de hecho todo funciona perfectamente, sin embargo ahora necesito agregar un pequeño matiz (el de que el message handler conozca quien es la instancia padre para enviarle a ella el mensaje) y veo que el tema de la herencia y los templates me da el problema comentado anteriormente.

Aunque no iba por ahí mi duda agradezco el interes Juan. :)
Por un stratos menos tenso

Juan Mellado

 Pues nada, lo siento. Pero si no es eso, entonces no entiendo lo que quieres hacer.  (nooo)  (está majo este icono)

Suerte






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.