2010-07-14 13 views
5

Tengo un problema con un par de clases de controlador de eventos que estoy tratando de escribir. Básicamente, la idea es tener una clase de controlador de eventos para cada grupo lógico de objetos. En la mayoría de los casos, los eventos se producen entre objetos y su controlador, pero en algunos casos también se envían eventos entre objetos del manejador.Llamando eliminar en dos punteros al mismo objeto

He escrito el código de tal manera que los eventos se colocan en una pila (stack como en la estructura creada usuario; los acontecimientos mismos se distribuyen utilizando new) y delete d después de su información se lee y actuar en consecuencia. Esto me está dando algunos problemas porque, en un caso, el evento se envía a lo largo de una cadena de tres manejadores. Diga, HandlerA envía new Event a HandlerB, que lo coloca en la pila y lo lee, enviándolo a HandlerC, que lo lee y realiza todo lo que necesita para realizarlo, después de lo cual delete es el puntero de evento y lo establece en NULL. Ahora, volvemos al HandlerB y, bueno, también quiere delete y NULL el puntero al evento. Pero el puntero es una variable local y termina borrando la misma dirección dos veces, dando una excepción.

¿Cómo se puede solucionar esto? ¿Necesitas usar uno de esos lujosos auto_ptr s (que todavía aprenden temprano), o me estoy perdiendo algo fundamental aquí?

+0

Los eventos se asignan en stack o se asignan en heap (usando new) y se almacenan en una estructura de datos de pila? – Naveen

+0

Los eventos se asignan en el montón usando new y se almacenan en una estructura de pila. Creo que debería cambiar la redacción anterior ... –

Respuesta

10

He escrito el código de tal manera que los eventos se colocan en una pila y se borran después de su información se lee y actuar en consecuencia.

Existe cierta confusión aquí - objetos en la pila debe ser no delete d. Los objetos creados con new (en el montón) deberían.

En general, debe definir una estrategia de propiedad clara para sus objetos en el montón. Cada objeto debe tener un propietario, y debe quedar claro quién es el propietario en cualquier momento. Ese propietario - y solo - deberá delete el objeto.

Es posible que también desee utilizar boost::shared_ptr (puede estar disponible también como std::tr1::shared_ptr, dependiendo de su compilador) en lugar de punteros sin formato. Esto mantiene el recuento de las referencias al objeto, y delete s cuando el recuento de ref se reduce a 0.

+0

Me refiero a una estructura de pila creada por el usuario, no en el sentido en que te referías. ¡Lo siento! –

+0

Creo que OP significa una estructura de datos de pila y no la pila. – Jackson

+0

@Kristian, ya veo, gracias por su aclaración. Entonces el problema no es tan malo como parecía al principio :-) –

6

Lo que quiere es un contenedor de puntero que para instancias utiliza el recuento de referencias para comprobar si otras variables hacen referencia a la misma instancia. La idea es que el objeto al que apunta el puntero solo se desasigna cuando ese objeto no es utilizado por ningún otro puntero. Ese tipo de punteros generalmente se denominan Smart Pointers. En C++, por ejemplo, puede usar los que proporciona Boost.

1

El problema es que no hay un propietario claro del puntero. Una solución serán los indicadores inteligentes como se señala en la respuesta de inflagranti. Alternativamente, podría dejar de reenviar el evento dos veces: cuando un controlador (Handler B en su ejemplo) recibe un evento que necesita reenviar a otro controlador, crea un nuevo evento en lugar de pasar el puntero al evento existente.

Dicho eso; Si desea dedicar tiempo a investigar sobre ellos, creo que la solución Smart Pointer es probablemente mejor.

Cuestiones relacionadas