Sono un vecchio C-dude che tenta di apprendere su C++ 11 effettuando il porting del mio vecchio framework state-machine da Da C a C++ 11. La mia idea è di avere una classe per la macchina di stato stessa e quindi classi annidate per gli stati all'interno. Gli stati possono essere gerarchici, cioè super- e substati. Il framework deve conoscere il superstato di uno stato e per questo ho un puntatore (state *superstate
) nella classe di stato nidificata.L'inizializzazione uniforme di membri di dati non statici C++ 11 non riesce per i puntatori ad altre classi della stessa classe base
Il mio problema è che intendevo impostare il puntatore superstato utilizzando il costruttore direttamente all'interno della classe della macchina, che dovrebbe essere possibile in C++ 11 con inizializzazione di membri di dati non statici, utilizzando l'inizializzazione uniforme. Ma qualche motivo non riesce a compilare (substateB3{superstateA}
) quando impostato su un altro tipo di stato/classe. Ma funziona bene se in seguito l'ho impostato utilizzando una funzione specifica (set_superstate
) per questo scopo, che ha lo stesso argomento del costruttore! E abbastanza divertente il costruttore è accettato se imposto il superstato a uno stato/classe dello stesso tipo (substateB2{substateB1}
).
sto usando gcc 4.7.0 (per ottenere il supporto per inizializzatori membro di dati non statici) ed ecco il mio codice:
// My state-machine framework (simplified)
struct machine {
struct state {
state() : superstate(nullptr) { } // No superstate => toplevel state!
state(state &superstate) : superstate(&superstate) { }
state *superstate;
void set_superstate(state &superstate) { this->superstate = &superstate; } // Non-ctor way to set superstate
};
};
// An example of a specific state-machine using my framework
struct Machine : machine {
struct SuperstateA : state {
} superstateA;
struct SubstateB : state {
} substateB1, // Compiles OK; gets its superstate set in Machine's ctor below
substateB2{substateB1}, // Compiles OK; but not correct superstate
substateB3{superstateA}; // gcc 4.7.0 error: could not convert ‘{((Machine*)this)->Machine::superstateA}’ from ‘<brace-enclosed initializer list>’ to ‘Machine::SubstateB’
Machine() { substateB1.set_superstate(superstateA); } // Compiles OK;
} myMachine;
Eventuali consigli o linee guida sono molto apprezzati, grazie! :)
Capisco che questo è un esercizio di apprendimento, ma si potrebbe voler almeno guardare un quadro di macchina di stato C++ moderno esistente come [Boost.MSM] (http://www.boost.org/libs/msm/) per una certa prospettiva. – ildjarn
In C++, non definire mai un tipo e un oggetto dello stesso tipo nella stessa istruzione. Questo è molto confuso da leggere e unidiomatico. –
Sembra che siano necessari anche i costruttori ereditari per il tuo sottostratoB. Non sono sicuro che GCC supporti già quelli. –