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

From:http://www.codeproject.com/KB/library/libreflection.aspx

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

 

 

#include "reflection.hpp"


/*****************************************************************************
    MAIN
 *****************************************************************************/


#include <list>
#include <string>
#include <iostream>
using namespace std;
using namespace agm::reflection;


void print_class(const Class &pclass)
{
    cout << "class name = " << pclass.getName() << endl;

    cout << "superclass = ";
    if (pclass.hasSuper()) cout << pclass.getSuper().getName();
    else cout << "none";
    cout << endl;

    cout << "fields:\n";
    for(Class::FieldList::const_iterator itField = pclass.getFields().begin();
        itField != pclass.getFields().end();
        ++itField)
    {
        const Field &field = *itField;
        cout << "    " << field.getAccess() << " " << field.getType() << " " << field.getName() << endl;
    }

    cout << "static fields:\n";
    for(Class::StaticFieldList::const_iterator itStaticField = pclass.getStaticFields().begin();
        itStaticField != pclass.getStaticFields().end();
        ++itStaticField)
    {
        const StaticField &field = *itStaticField;
        cout << "    " << field.getAccess() << " " << field.getType() << " " << field.getName() << endl;
    }

    cout << "methods:\n";
    for(Class::MethodList::const_iterator itMethod = pclass.getMethods().begin();
        itMethod != pclass.getMethods().end();
        ++itMethod)
    {
        const Method &method = *itMethod;
        cout << "    " << method.getAccess();
        if (method.isVirtual()) cout << " " << "virtual";
        cout << " " << method.getType() << " " << method.getName() << method.getArgs() << endl;
    }

    cout << "properties:\n";
    for(Class::PropertyList::const_iterator itProperty = pclass.getProperties().begin();
        itProperty != pclass.getProperties().end();
        ++itProperty)
    {
        const Property &property = *itProperty;
        cout << "    " << property.getType() << " " << property.getName() << endl;
    }

    cout << "\n-----------------------------------------------------------\n";
}


class Foo {
public:
    CLASS(Foo, NullClass);

    PROPERTY(int, length);

    METHOD(public, void, action, ()) {
        cout << "Foo::action();\n";
    }

    METHOD(public, void, action1, (int i)) {
        cout << "Foo::action1(" << i << ");\n";
    }

    STATIC_METHOD(public, int, get_code, ()) {
        cout << "Foo::get_code();\n";
        return 1;
    }

    STATIC_METHOD(public, int, get_code1, (int i)) {
        cout << "Foo::get_code1(" << i << ");\n";
        return i + 1;
    }

    STATIC_METHOD(public, void, print_code, ()) {
        cout << "Foo::print_code();\n";
    }

    STATIC_METHOD(public, void, print_code1, (int i)) {
        cout << "Foo::print_code1(" << i << ");\n";
    }

    Foo() {
        m_length = 0;
    }

private:
    int m_length;

    int get_length() const {
        cout << "get_length();\n";
        return m_length;
    }

    void set_length(int l) {
        cout << "set_length(" << l << ");\n";
        m_length = l;
    }
};


class Bar {
public:
    CLASS(Bar, NullClass);
};


int main()
{
    Foo foo1;
    const Class &foo_class = foo1.getClass();
    print_class(foo_class);

    getchar();
    return 0;
}

 

 

#include "reflection.hpp"
using namespace agm::reflection;
using namespace std;


class Widget {
public:
    CLASS(Widget, NullClass);

    PROPERTY(int, x);
    PROPERTY(int, y);
    PROPERTY(int, width);
    PROPERTY(int, height);
    PROPERTY(bool, visible);
    PROPERTY(bool, enabled);

    STATIC_FIELD(public, const int, version);

    METHOD(public, bool, add, (Widget *child));

    STATIC_METHOD(public, const char *, get_version_string, ());
private:
    FIELD(private, int, m_x);
    FIELD(private, int, m_y);
    FIELD(private, int, m_width);
    FIELD(private, int, m_height);
    FIELD(private, bool, m_visible);
    FIELD(private, bool, m_enabled);

    int get_x() const {
        return m_x;
    }

    void set_x(int v) {
        m_x = v;
    }

    int get_y() const {
        return m_y;
    }

    void set_y(int v) {
        m_y = v;
    }

    int get_width() const {
        return m_width;
    }

    void set_width(int v) {
        m_width = v;
    }

    int get_height() const {
        return m_height;
    }

    void set_height(int v) {
        m_height = v;
    }

    bool get_visible() const {
        return m_visible;
    }

    void set_visible(bool v) {
        m_visible = v;
    }

    bool get_enabled() const {
        return m_enabled;
    }

    void set_enabled(bool v) {
        m_enabled = v;
    }

};


const int Widget::version = 1;


const char *Widget::get_version_string()
{
    return "1.0";
}


bool Widget::add(Widget *child)
{
    cout << "Added widget of class " << child->getClass().getName() << endl;
    if (child == 0) return false;
    return true;
}


class Label : public Widget {
public:
    CLASS(Label, Widget);
protected:
private:
};


int main1()
{
    Widget wgt;

    wgt.x = 5;
    int x = wgt.x;

    wgt.visible = true;
    bool v = wgt.visible;

    cout << "wgt.x=" << x << endl;
    cout << "wgt.visible=" << v << endl;

    getchar();
    return 0;
}


int main2()
{
    Widget wgt;

    wgt.x = 5;
    wgt.x++;
    int x = wgt.x;
    bool is_6 = wgt.x == 6;

    cout << "wgt.x=" << x << endl;
    cout << "wgt.x == 6 ? " << is_6 << endl;

    getchar();
    return 0;
}


int main3()
{
    Widget wgt;

    for(Class::PropertyList::const_iterator it = wgt.getClass().getProperties().begin();
        it != wgt.getClass().getProperties().end();
        ++it)
    {
        const Property &prop = *it;
        cout << prop.getType() << " " << prop.getName() << endl;
    }

    getchar();
    return 0;
}


int main4()
{
    Widget wgt;
   
    const Property &prop = wgt.getClass().getProperty("width");

    cout << prop.getType() << " " << prop.getName() << endl;

    prop.set(&wgt, 5);
    int w;
    prop.get(w, &wgt);

    cout << prop.getName() << " = " << w << endl;

    getchar();
    return 0;
}


int main()
{
    Widget wgt;
    Label lbl;

    bool ok;
    wgt.getClass().getMethod("add").invoke(ok, &wgt, (Widget *)&lbl);
   
    getchar();
    return 0;
}

你可能感兴趣的:(reflection)