Click here to Skip to main content
12,622,913 members (30,177 online)
Click here to Skip to main content
Add your own
alternative version

Stats

108.3K views
1.7K downloads
54 bookmarked
Posted

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

, 2 Nov 2004
Rate this:
Please Sign up or sign in to vote.
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.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Achilleas Margaritis
Software Developer (Senior)
Greece Greece
No Biography provided

You may also be interested in...

Pro

Comments and Discussions

 
Generaltypeless parameters Pin
Member 1811246-Oct-08 6:26
memberMember 1811246-Oct-08 6:26 
GeneralWindows CE compilation Pin
DuvidaCruel9-Feb-07 10:11
memberDuvidaCruel9-Feb-07 10:11 
GeneralLibReflection for gcc Pin
Anonymous3-May-05 5:51
sussAnonymous3-May-05 5:51 
QuestionArrays? Pin
neo26007776-Apr-05 10:30
memberneo26007776-Apr-05 10:30 
GeneralAn Update Version Posted Pin
my203829-Mar-05 8:52
membermy203829-Mar-05 8:52 
GeneralNew Changes Made to LibReflection Pin
my203823-Mar-05 11:22
membermy203823-Mar-05 11:22 
Okay, here are the things that I added to your LibReflection library:

(1) Constructor information is now captured. You can actually invoke a constructor -- it will automatic create an object using the new operator. And the newInstance() method on the class will automatically called default constructor if one is defined.

(2) Method args type and list. Method, Static method and Constructor parameter and return type (std::type_info) can be retrieved.

(3) Class Method, Static Method, Constructor can be overloaded. But the MACRO to defined them wasn't as nice.

(4) port to gcc. Well, I only use gcc, so that is the only choice.

(5) added class registary to lookup or listing of all known classes

(6) When invoking a method object with type mismatched, the exception threw will include detailed information about which parameter/ret/object ref are mismatched. This should greater improve the ability to fix it.

(7) Full class name (including namespace) are now captured and returned.

(8) NEW! NEW! Automatic casting of object class are now working. If your method like a Base * but you pass in a Dervied *, it will automatic cast to the Base *. Also you can cast any class * cast to void *. This will allow alot of code to work in a generic way. Requirement is that both Base & Dervied must be defined in the reflection. This works in reference as well (i.e. Derviced & to Base &) . For example, if your method is defined in class Dervied as

Dervied * createThis(Base * b);

You can invoke it using:

Base *result_ptr;
Dervied d;

d.getClass().getMethod("createThis").invoke(result_ptr, &d, &d);


(9) NEW! NEW! NEW! Dynamic pointer casting are now working. The known object pointer will automatic test for dynamic castable to its dervied type. This allow you to invoke method using Base class pointer. For the sample above, we can invoke it as:

Base *p = &d;
d.getClass().getMethod("createThis").invoke(result_ptr, p, &d);

(10) Work in template class as well.

Limitation (same as original) :
An instance of the class must be created before the class is "known".

Single inhertiance only. no virtual base class.

Some of the implicit conversion originally done by the compiler will not be performed. e.g. long -> int, const char * -> string, etc

Let me know if there is a way I can send you back the changes...

GeneralRe: New Changes Made to LibReflection Pin
WREY28-Mar-05 1:14
memberWREY28-Mar-05 1:14 
GeneralRe: New Changes Made to LibReflection Pin
my203828-Mar-05 7:40
membermy203828-Mar-05 7:40 
GeneralNot totally true. Pin
WREY28-Mar-05 9:23
memberWREY28-Mar-05 9:23 
GeneralRe: Not totally true. Pin
my203829-Mar-05 8:53
membermy203829-Mar-05 8:53 
GeneralCompile Error in VS.NET 1.1 Pin
colormegjian22-Mar-05 4:26
membercolormegjian22-Mar-05 4:26 
GeneralRe: Compile Error in VS.NET 1.1 Pin
tomthorne22-Apr-05 8:23
membertomthorne22-Apr-05 8:23 
GeneralRe: Compile Error in VS.NET 1.1 Pin
derchoff6-Oct-05 1:15
memberderchoff6-Oct-05 1:15 
QuestionCan i use it in BCB? Pin
FlameBlade17-Feb-05 3:41
memberFlameBlade17-Feb-05 3:41 
GeneralContact Pin
psyclonist (Stephan K.)22-Nov-04 2:41
susspsyclonist (Stephan K.)22-Nov-04 2:41 
QuestionCan Instance be Created Dynamicly? Pin
Laisser21-Nov-04 7:21
memberLaisser21-Nov-04 7:21 
GeneralVery Interesting! Pin
ggerules10-Nov-04 6:19
memberggerules10-Nov-04 6:19 
GeneralCool! Pin
Jim Crafton2-Nov-04 15:15
memberJim Crafton2-Nov-04 15:15 
GeneralRe: Cool! Pin
axilmar3-Nov-04 3:37
memberaxilmar3-Nov-04 3:37 
GeneralRe: Cool! Pin
my203815-Mar-05 11:27
membermy203815-Mar-05 11:27 
GeneralDude Pin
armentage2-Nov-04 10:23
memberarmentage2-Nov-04 10:23 
GeneralRe: Dude Pin
axilmar2-Nov-04 10:42
memberaxilmar2-Nov-04 10:42 
GeneralRe: Dude Pin
Dave Handley3-Nov-04 7:10
memberDave Handley3-Nov-04 7:10 
GeneralRe: Dude Pin
Anders Dalvander13-Nov-04 3:03
memberAnders Dalvander13-Nov-04 3:03 
GeneralRe: Dude Pin
Dave Handley13-Nov-04 4:08
memberDave Handley13-Nov-04 4:08 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.161128.1 | Last Updated 2 Nov 2004
Article Copyright 2004 by Achilleas Margaritis
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid