Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reflection in C++

I've been working for years with Java. During those years, I've made extensive (or maybe just frequent) use of reflection, and found it useful and enjoyable. But 8 months ago I changed my job, and now Java is just a memory, and I'm getting my hands on C++. So now I'm wondering if there is any reflection mechanism in C++. I've read about RTTI but I feel it's by no means the power of Java (or other languages) reflecion. I'm beggining to think that there's no way to do this in C++. Am I wrong?

like image 356
aitor Avatar asked May 12 '09 05:05

aitor


People also ask

What is reflection in C?

Reflection provides objects (of type Type) that describe assemblies, modules, and types. You can use reflection to dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object and invoke its methods or access its fields and properties.

Does C support reflection?

Reflection is supported through the common language runtime, not by the Microsoft C++ compiler. Although you used this code to inspect an assembly that you defined, you can also use this code to inspect .

What is reflection in language?

Reflection can be defined as the deliberate and purposeful act of thinking which centers on ways. of responding to problem situations in language teaching and learning. It involves not simply a. sequence of ideas, but a consecutive ordering in such a way that the teacher and learner leans.

What do you use reflection for in programming?

Reflection is a feature in the Java programming language. It allows an executing Java program to examine or "introspect" upon itself, and manipulate internal properties of the program. For example, it's possible for a Java class to obtain the names of all its members and display them.


2 Answers

Since C++ standard does not cover such concept as "metadata", there's no portable (across different compilers and platforms, for that matter) method of run-time reflection other than RTTI you already mentioned.

In C++, there's also a possibility of compile-time reflection (think boost::type_traits and boost::type_of), but it's limited as well compared to, say, Nemerle or LISP.

Most major frameworks (MFC, Qt, etc.) allow you to extract metainformation at run-time, but they require all kinds of special annotations for it to work (see RUNTIME_CLASS et al as an example).

like image 160
Anton Gogolev Avatar answered Nov 15 '22 23:11

Anton Gogolev


If you are looking for a totally general way to manipulate objects at runtime when you don't know their types at compile time in C++, you essentially need to:

  1. Define an interface (abstract base class with all pure virtual methods and no members) for each capability that a class might support.
  2. Each class must inherit virtually from all interfaces that it wants to implement (possibly among other classes).

Now, suppose pFoo holds an interface pointer of type IFoo* to some object x (you don't need to know x's concrete type). You can see whether this object supports interface IBar by saying:

if (IBar* pBar = dynamic_cast<IBar*>(pFoo)) {
    // Do stuff using pBar here
    pBar->endWorldHunger();
} else {
    // Object doesn't support the interface: degrade gracefully
    pFoo->grinStupidly();
}

This approach assumes you know all relevant interfaces at compile time -- if you don't, you won't be able to use normal C++ syntax for calling methods anyway. But it's hard to imagine a situation where the calling program doesn't know what interfaces it needs -- about the only case I can think of would be if you want to expose C++ objects via an interactive interpreter. Even then, you can devise an (ugly, maintenance-intensive) way of shoehorning this into the above paradigm, so that methods can be called by specifying their names and arguments as strings.

The other aspect to consider is object creation. To accomplish this without knowing concrete types, you'll need a factory function, plus unique identifiers for classes to specify which concrete class you want. It's possible to arrange for classes to register themselves with a global factory upon startup, as described here by C++ expert Herb Sutter -- this avoids maintaining a gigantic switch statement, considerably easing maintenance. It's possible to use a single factory, though this implies that there is a single interface that every object in your system must implement (the factory will return a pointer or reference to this interface type).

At the end of the day, what you wind up with is basically (isomorphic to) COM -- dynamic_cast<IFoo*> does the same job as QueryInterface(IID_IFoo), and the base interface implemented by all objects is equivalent to IUnknown.

like image 34
j_random_hacker Avatar answered Nov 15 '22 23:11

j_random_hacker