Riguardo a 1. e 2.
Quello che stai descrivendo in realtà non mi sembra una "macchina dello stato" (E temo di non poter dare molto senso all'esempio nel contesto di ciò che hai descritto).
Una macchina a stati in genere comporta la transizione tra stati noti quando viene colpita una condizione per quello stato particolare; sembra più che stai cercando di memorizzare un elenco di abbonamenti di eventi che possono cambiare arbitrariamente nel tempo - per questo probabilmente hai bisogno di qualcosa come il pattern Observer.
Riguardo a 3.
Non ho mai riscontrato alcuna situazione in C ++ in cui una lista concatenata scritta a mano sia affatto desiderabile; dovresti preferire le librerie standard come regola generale. std :: deque o std :: map potrebbe essere un buon punto di partenza come mezzo per memorizzare sottoscrittori / osservatori.
Utilizzando un moderno compilatore C ++ 11, è possibile implementare un std::map< std::string, std::function<T>>
per ciascuno degli eventi a cui si desidera sottoscrivere (con la stringa / chiave utilizzata per identificare l'obiettivo dell'osservatore per la successiva rimozione o modifica dell'abbonamento ).
std :: funzione < T > ti permette di usare qualsiasi tipo di oggetto callable, lambda, funzione o raccoglitore di funzione al curry come abbonato, la cui firma callable corrisponde a T
.
ad esempio, con std::function< void() >
potresti ragionevolmente usare
std::function<void()> fred = [](){ std::cout << "hello world"; };
fred(); // call the lambda
o
struct foo {
void operator() () { std::cout << "hello world"; }
};
std::function<void()> bob = foo();
bob(); // call the functor
o
void foo() { std::cout << "hello world"; }
// ---------------------------------------
std::function<void()> blah = foo;
blah(); // call the function
o
class MyClass
{
public:
void func() { std::cout << "hello world" << std::endl; }
};
// -----------------------------------------------------
MyClass obj;
std::function<void()> meow = std::bind( &MyClass::func, obj );
meow(); // Call the member function using the object
Da questo, dovrebbe essere abbastanza facile immaginare un contenitore pieno di oggetti std :: function. Naturalmente, se necessario, puoi anche avvolgere la funzione std :: in un'altra classe (il che ti porterà un po 'più vicino al pattern GoF Observer).