8

Is there any efficient way in C++ of generating an ID unique to the class, not to the instance? I'm looking for something of this level of simplicity (this generates an ID for every instance, not for every class type):

MyClass::MyClass()
{
    static unsigned int i = 0;
    id_ = i++;
}

Edit: Why I want unique IDs.

I'm writing a game. All entities in my game will have different states they can be in (walking left, jumping, standing, etc); these states are defined in classes. Each state needs to have its own ID so I can identify it.

Paul Manta
  • 30,618
  • 31
  • 128
  • 208
  • `typeid` or `type_info` although these are usually considered for debug purposes only so I'd just use an enum or string identifier. What are you trying to accomplish that requires you to have a list of type ids as there probably is a better way ... C++ is strongly typed so all types already have inherent uniqueness. – AJG85 Jun 15 '11 at 22:28
  • @AJG85 Is it bad practice to use `typeid` in production code? It seems like the best thing to do for me right now. – Paul Manta Jun 15 '11 at 22:55
  • 1
    I would consider it bad practice in production code. Firstly because it's a runtime construct which is not guaranteed to return anything human readable for `.name` and secondly because C++0x is introducing `decltype` and `auto` which should alleviate some of the type checking need within template code which is probably the only place you should be considering something like this. – AJG85 Jun 15 '11 at 23:07

3 Answers3

14

You can try this, but it's not-deterministic.

int id_count = 0;

template <typename T>
int get_id()
{
    static int id = id_count++;
    return id;
}

Then just use:

get_id<int>(); // etc.

Of course, this isn't thread safe.

Again, it's not deterministic: the IDs are generated the first time you call the function for each type. So, if on one run you call get_id<int>() before get_id<float>() then on another run you call them the other way round then they'll have different IDs. However, they will always be unique for each type in a single run.

Peter Alexander
  • 53,344
  • 14
  • 119
  • 168
  • This is a good solution since I my application isn't multi-threaded. The problem is I can't know all types at compile-time. Only the bases classes will be known at compile time, the derived ones will be defined in scripts. I need an unique ID for every derived class. – Paul Manta Jun 15 '11 at 22:29
  • @Paul: If the types come from scripts then you'll need a solution that is specific to the scripting language you are using. – Peter Alexander Jun 15 '11 at 22:32
  • I hoped there was some clever way of joggling with static variables that allows the base class (known at compile time) to generate unique IDs for every class that derives from it. – Paul Manta Jun 15 '11 at 22:34
  • 2
    @Paul: As far as the C++ portion of your code is concerned, nobody does derive from your class. You aren't concerned with C++; the solution to your problem depends on your scripting language, and how it interfaces with the existing C++ code. – Dennis Zickefoose Jun 15 '11 at 23:02
4

Basically you are asking for a custom rolled RTTI solution, that you can selectively apply to classes.

This can start from very crude preprocessor stuff like :

#define DECLARE_RTTI_CLASS(a) class a {  \
     inline const char * class_id() { return #a };

.. to a more sophisticated solutions that track inheritance etc, essentially partially duplicating compiler RTTI functionality. For an example, see Game Programming Gems #2, Dynamic Type Information

Previous discussions on gamedev on the same subject are also worth reading

kert
  • 2,161
  • 21
  • 22
1

Use your MyClass as a primitive, and incorporate a static instance of one into each class you want to ID.

class MyOtherClass1 {
    static MyClass id;
};

class MyOtherClass2 {
    static MyClass id;
};

[etc.]
Nemo
  • 70,042
  • 10
  • 116
  • 153
  • I know that, but I was looking for something more 'automatic'. Doing it by hand, like this, is prone to mistakes. :) – Paul Manta Jun 15 '11 at 22:27
  • @Paul: unless you use some tool like OpenC++ (is it even maintained any more), you can't ask the compiler to automatically enrich all class instances: they only contain what's explicitly listed in each. But, if you program depends on such fields to be there then you should get a compile-time error if they're absent, which leaves your mysterious scripting language that's your yet to provide details of (it's pretty wild that it allows you to derive from C++ classes...). – Tony Delroy Jun 16 '11 at 01:05
  • @Tony The language is Python. – Paul Manta Jun 16 '11 at 05:03
  • @Paul: thanks for letting me know - my current team uses Python quite a lot, not embedded though - opens up possibilities :-) – Tony Delroy Jun 16 '11 at 05:29