in C++

5

Dopo aver programmato per qualche tempo con i framework C obiettivo iOS e Mac, ho imparato ad amare il modello di notifica generico implementato dalle classi NSNotificationCenter e NSNotification. Tornando al C++, che è sempre stato il mio linguaggio di scelta per la maggior parte delle cose, mi trovo a cercare di replicare questo modello e credo che in realtà ci dovrebbe essere già un'implementazione generica di classi C++ simili che offrono supporto per questo.in C++

Sembra che lo schema sia in qualche modo più difficile da implementare in C++ rispetto all'Object C a causa della natura più dinamica dell'ultimo, ma sembra tutt'altro che impossibile. Ho esaminato le librerie di boost perché sono in genere fantastiche ed ero triste non trovarvi la fortuna lì. Anche se le funzioni boost :: bind, boost :: lamda, boost :: sembrano fare la maggior parte del lavoro. Ho perso qualcosa di ovvio? C'è qualcosa di già esistente là fuori che mi permetterebbe di replicare facilmente il comportamento di NSNotification/NSNotificationCenter?

+0

Hai provato Boost.signals? – anno

+0

Darei un'occhiata, grazie per il suggerimento. – jbat100

+0

Con un approccio leggermente diverso, Qt ha implementato "segnali e slot" tramite uno strumento di pre-elaborazione dedicato (compilatore di meta oggetti moc <->). Tuttavia, è solo ragionevole usarlo se qt ui si adatta alle tue esigenze. –

risposta

1

Seguendo la raccomandazione di @ anno di guardare il segnale boot ::, dopo l'esame sembra una possibile opzione anche se, come previsto, non è così semplice come le soluzioni oggettive in C. Guardando attraverso il boost::signal tutorial, ho pensato che avrei affrontato gli aspetti più rilevanti per il problema in questione.


Per creare mittenti di notifica:

consideri un servizio di news di consegna semplice, in cui i client si connettono a un provider di notizie che poi invia notizia a tutti i client connessi come arriva informazioni. Il servizio di notizie di consegna può essere costruito in questo modo:

class NewsItem { /* ... */ }; 
boost::signal<void (const NewsItem&)> deliverNews; 

L'obiettivo di deliverNews è quello di informare gli osservatori che un NewsItem è stato generato.


osservatori possono essere aggiunti come segue (utilizzando la libreria boost :: bind):

I clienti che desiderano ricevere aggiornamenti sufficiente collegare un oggetto funzione che può ricevere le notizie ai deliverNews segnale. Per esempio, possiamo avere una speciale area di messaggio nella nostra applicazione appositamente per le notizie, ad esempio ,:

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)); 

Per affrontare il problema della rimozione osservatori che sono stati disallocati dalla lista, boost :: segnale offre la seguente soluzione

Tuttavia, cosa succede se l'utente chiude l'area dei messaggi notizie, distruggendo l'oggetto newsMessageArea che deliverNews conosce? Molto probabilmente, si verificherà un errore di segmentazione . Tuttavia, con Boost.Signals è necessario rendere NewsMessageArea solo tracciabile e lo slot che coinvolge newsMessageArea verrà disconnesso quando newsMessageArea è distrutto.La classe NewsMessageArea è fatto rintracciabile derivando pubblicamente dalla boost :: segnali :: classe rintracciabile, ad esempio:

struct NewsMessageArea : public MessageArea, public boost::signals::trackable 
{ 
    // ... 
}; 

A questo punto v'è una limitazione significativa per l'utilizzo del rintracciabili oggetti creazione di connessioni slot: oggetti funzione creati utilizzando Boost.Bind sono compresi, in modo tale che puntatori o riferimenti a oggetti tracciabili passati a boost :: bind vengano trovati e tracciati.

2

In teoria si potrebbe creare una classe che ha un vettore di puntatori a funzione da chiamare quando una notizia certa si chiama - Una classe che ha un dizionario in cui gli oggetti sono i vettori di funzioni da chiamare quando una notifica viene spinto

2

Oltre ai boost pacchetti menzionati in altre risposte, un'altra opzione è poco::NotificationCenter.

Questa implementazione è più vicino al quadro di notifica di cacao, come specificamente discusso su Poco di documentation:

La classe NotificationCenter è fondamentalmente un'implementazione C++ della classe NSNotificationCenter trovato in Cocoa (o OpenStep) di Apple.