AGM::LibReflection: A reflection library for C++.






4.97/5 (15 votes)
Nov 2, 2004

143852

1847
Description of the library AGM::LibReflection.
Introduction
LibReflection is a little library (well, a header to be specific) that gives reflection capabilities to C++ classes. When we talk about reflection, we don't mean just RTTI, but a rich palette of capabilities useful in every day programming:
- specify and examine class inheritance
- declare and examine normal and static fields
- declare and examine normal, virtual, and static methods
- declare and use properties and events
- set and get field values
- call methods and get results
- create instances without having the headers at hand, by using a class registry
And all the above almost happen automatically, with very few macros that the programmer has to put in the application's classes...and you also get the added benefit of class properties and events, something that C++ does not provide by default.
Demo
Using LibReflection is very easy. The following piece of code shows a class with fields, properties and methods, all reflected in the class' Class
object:
//what you need to include #include "reflection.hpp" //namespace usage using namespace agm::reflection; //example base class class Base { public: //needed so as that the class gets reflection capabilities CLASS(Base, NullClass); //a reflected property PROPERTY(int, length); //a reflected method METHOD(public, bool, processLength, (int l)); private: //a reflected field FIELD(private, int, m_length); //property getter int get_length() const { return m_length; } //property setter void set_length(int l) { m_length = l; } }; //a reflected method implementation bool Base::processLength(int l) { return l == m_length; } //a derived class class Derived : public Base { public: //derived reflected class CLASS(Derived, Base); }; //for the demo #include <iostream> using namespace std; int main() { //a class instance Derived derived; //get the class of the Derived class const Class &derived_class = derived.getClass(); //print the class name cout << derived_class.getName() << endl; //print the the m_length field const Field &length_field = derived_class.getField("m_length"); cout << length_field.getType() << " " << length_field.getName() << endl; //print the the length property const Property &length_prop = derived_class.getProperty("length"); cout << length_prop.getType() << " " << length_prop.getName() << endl; //print the 'processLength()' method const Method &process_length_method = derived_class.getMethod("processLength"); cout << process_length_method.getType() << " " << process_length_method.getName() << process_length_method.getArgs() << endl; //set the length property cout << "using length property" << endl; length_prop.set(&derived, 10); int i; length_prop.get(i, &derived); cout << "length = " << i << endl; //calling the length method cout << "calling bool Base::processLength(int)" << endl; bool b; process_length_method.invoke(b, (Base *)&derived, 10); cout << "processLength=" << b << endl; getchar(); return 0; }
Documentation
For more information, you can check out my little site here.