Siguiendo la recomendación de @anno de mirar boot :: signal, después del examen parece una posible opción aunque, como se esperaba, no es tan simple como las soluciones del objetivo C. Mirando a través del boost::signal tutorial, pensé que revisaría los aspectos más relevantes para el problema en cuestión.
Para crear remitentes de notificación:
Considere un servicio de distribución de noticias simple, donde los clientes se conectan a un proveedor de noticias que envía noticias a todos los clientes conectados como llega la información. El servicio de entrega de prensa puede ser construido de esta manera:
class NewsItem { /* ... */ };
boost::signal<void (const NewsItem&)> deliverNews;
El objetivo de deliverNews
es informar a los observadores de que un NewsItem
se ha generado.
Los observadores pueden ser añadidos como sigue (usando la biblioteca de impulso :: bind):
Los clientes que deseen recibir actualizaciones de noticias sólo tiene que conectar un objeto de función que puede recibir las noticias a los deliverNews señal. Por ejemplo, podemos tener un área especial mensaje en nuestra aplicación específicamente para las noticias, por ejemplo ,:
struct NewsMessageArea : public MessageArea
{
public:
// ...
void displayNews(const NewsItem& news) const
{
messageText = news.text();
update();
}
};
// ...
NewsMessageArea newsMessageArea = new NewsMessageArea(/* ... */);
// ...
deliverNews.connect(boost::bind(&NewsMessageArea::displayNews, newsMessageArea, _1));
Para abordar el problema de la eliminación de los observadores que han sido desasignado de la lista, boost :: señal ofrece la siguiente solución
Sin embargo, lo que si el usuario cierra el área de mensajes de noticias, destruyendo el objeto newsMessageArea que deliverNews conoce? Lo más probable es que se produzca un error de segmentación . Sin embargo, con Boost.Signals uno necesita solo hacer que NewsMessageArea sea rastreable, y la ranura que implica newsMessageArea se desconectará cuando newsMessageArea es destruido.La clase NewsMessageArea se hace rastreable derivando públicamente desde el impulso :: señales :: clase rastreable, por ejemplo:
struct NewsMessageArea : public MessageArea, public boost::signals::trackable
{
// ...
};
En este momento no es una limitación importante para el uso de rastreables objetos en hacer conexiones de ranuras: objetos de función construidos usando Se entienden Boost.Bind, tales que los punteros o las referencias a objetos rastreables pasados a boost :: bind se encontrarán y se rastrearán.
¿Has probado Boost.signals? – anno
Voy a echar un vistazo, gracias por la sugerencia. – jbat100
Con un enfoque ligeramente diferente, Qt ha implementado "señales y ranuras" a través de una herramienta de preprocesamiento dedicada (moc <-> metaobjeto compilador). Sin embargo, solo es razonable usarlo si qt ui se ajusta a sus necesidades. –