tags:

views:

738

answers:

5

I've been reading a bit about what metaclasses are, but I would like to know if they can be achieved in C++.

I know that Qt library is using MetaObjects, but it uses an extension of C++ to achieve it. I want to know if it is possible directly in C++.

Thanks.

+3  A: 

Hi,

Several of the patterns in the book "Design Patterns" by Gamma, et al have similar features to the metaclass concept. The "Strategy" pattern allows you to customize object behavior at creation time, for example. The letter-envelope idiom is another close match. Neither let you customize the interface to the class, though.

In COM, the IDispatch interface allows for dynamically adding methods/attributes to an object at runtime. It means giving up standard c++ method calls, though. Every call goes through the same method, which takes an index or string key into a user-maintaned method/property table and all parameters must be passed as an array of objects.

Using those two techniques you can get the flexibility of metaclasses, but it is a much harder slog thanks to having no syntactic goodness or runtime/compiler help.

Dave

David Gladfelter
+1  A: 

Afraid not... At least not natively.

Having a metaclass would generally require that there would be a runtime object representing a class, as is the case in Java.

In C++, classes do not have a runtime representation. Their manifestations occur in things like the virtual table. But in many ways they operate like C functions with all the OOP functioning almost as a glue code.

That being said, there are OOP patterns for many things that you may want to implement with a metaclass in other languages. You could also "simulate" your own object system.

Uri
+3  A: 

If the working definition of metaclass is "a language entity whose instantiations are themselves classes," then generics are metaclasses in C++:

#include <iostream>
using namespace std;

template <typename T>
class Meta {
public:
    Meta(const T&init) : mData(init) {}
// ...
private:
    T mData;

};

int main(int, char **) {
  cout << "The size of Meta<double> is " << sizeof(Meta<double>) << endl ;
  return 0;
}

The use of Meta<double> in the antepenultimate line compels the compiler to instantiate the Meta<double> class; the sizeof operator operates upon Meta, thus demonstrating that this is not simply semantic sugar and that the class has been instantiated. The program is complete even though no objects of type Meta are instantiated.

Thomas L Holaday
+3  A: 

C++ Doesn't have built-in support for meta-classes (not in the Python/Objective-C way), however you can manually mimic the behavior of meta-classes. The basics are pretty simple, you create an extra class with a longer lifespan (Singleton, static object or the Construct On First Use Idiom) that is able to create and manipulate it's corresponding class. (In Objective-C the meta-class generally contains 'static' member variables, the memory allocation/deallocation routines et cetera).

What Qt has done is, they took the concept of meta-classes and modified it so that they can support some form of Reflection (and RTTI on systems that don't support it). Implementing this will require either a lot of macro magic or a custom compiler (such as they've chosen to use).

Generally though, most of the features a regular meta-class provides are already provided by the C++ language; just in a different form. And really, the only reason you'd want meta-objects would be for reflection purposes, there are different ways to implement reflection in C++ as outlined in this document.

Besides that, if you're really set on a Objective-C-style meta-class system, I'm not aware of any libraries that do that but there might very well be. On the other hand, rolling your own shouldn't be that difficult either.

Jasper Bekkers
+1  A: 

It's possible to create meta-classes, however C++ is not about that, it's about statically compile-time based implementations, not runtime flexibility.

Anyways it depends if you want Meta-Classes with methods or just Meta-Classes with data, the Data classes can be implemented with Boost constructs like boost::any, and if you want Classes with methods, you can use boost::bind to bind methods to the object, or you can implement them on your own with a single-entry point interface like COM-objects.

However the "real" C++ way is to use generics so it can all be determined at compile-time, for best performance.

To be honest, I've seen very few systems, although I have seen some, that truly need runtime flexibility, in most cases objects are born and die the same class, or at least enough to spend 95% of their lifetime as a single class once they come out of their factory.

So in many situations one finds themselves paying too much for runtime meta-classes. Of course there is the school of thought that this provides better developer performance, but in many situations, each line of code will be run on hardware a few hundred million times more than the time it took to write it. So you can think about compile-time and runtime classes as paying up front or leasing for-ever. Personally I like to pay up front.

Robert Gould