Sembra che tu abbia già trovato la soluzione, ma mi espanderò un po '.
Quello che stai chiamando si chiama Reflection
, ovvero la capacità di un oggetto di descriversi.
La maggior parte delle lingue implementa la riflessione grazie ai metadati, in Python, ad esempio, le funzioni e gli attributi di un oggetto sono memorizzati in un elemento del dizionario.
C++ non ha alcun sistema di riflessione nativo a differenza di C# o Java, che impedisce (ad esempio) questo tipo di stampa/serializzazione o deserializzazione automatica.
Tuttavia, C++ dispone di un supporto per metaprogrammazione molto potente che ci consente (tramite l'uso di modelli) di emulare il riflesso (in fase di compilazione). Di solito questo viene fatto usando Boost.Fusion, questa libreria è pensata per passare dal tempo di compilazione a quello di esecuzione.
Come nell'esempio illustrato nel collegamento, la macro consente di prendere uno standard struct
e di fornire l'interfaccia necessaria per essere considerata Fusion.Sequence.
Un altro esempio potrebbe essere quello di utilizzare Fusion.Vector
o Fusion.Map
per memorizzare gli attributi della classe e poi esporre questa sequenza per metodi automatici di stampa/di serializzazione/deserializzazione.
Tuttavia, esiste un limite a questo sistema: la metaprogrammazione non si adatta bene alla programmazione OO.
struct Base { char a; }; // Adapt
struct Derived: Base { char b; }; // Adapt
void print(Base const& b) { boost::fusion::for_each<Base>(b, Print()); }
sarà stampare solo il membro del Base
(qui a
).Quando si utilizza il polimorfismo, è necessario utilizzare metodi virtual
in un punto o un altro :)
fonte
2010-05-03 15:37:50
Ebbene, dopo aver scritto questa domanda, ho casualmente fatto google e trovato sotto discussione http://stackoverflow.com/questions/1878285/iterate-over-struct-easily-display-struct-fields-and-values-in-a-richedit-box Penso che risponda a tutti i miei dubbi. Grazie a tutti per la risposta però. – Zhinkaas