deimus
deimus

Reputation: 9865

Best Practice : How to get a unique identifier for the object

I've got several objects and need to generate a unique identifier for them which will not be changed/repeated during the lifetime of each object.

Basically I want to get/generate a unique id for my objects, smth like this

int id = reinterpret_cast<int>(&obj);

or

int id = (int)&obj;

I understand the codes above are bad ideas, as int might not be large enough to store the address etc.

So whats the best practice to get a unique identifier from the object, which will be a portable solution ?

Upvotes: 19

Views: 48005

Answers (6)

hcc23
hcc23

Reputation: 1280

When I looked into this issue, I fairly quickly ended up at the Boost UUID library (universally unique identifier, http://www.boost.org/doc/libs/1_52_0/libs/uuid/). However, as my project grew, I switched over to Qt's GUID library (globally unique identifier, https://doc.qt.io/qt-5/quuid.html).

A lesson learned for me though was to start declaring your own UUID class and hide the implementation so that you can switch to whatever you find suitable later on.

I hope that helps.

Upvotes: 6

dhavenith
dhavenith

Reputation: 2048

Depending on your "uniqueness"-requirements, there are several options:

  • If unique within one address space ("within one program execution") is OK and your objects stay where they are in memory then pointers are fine. There are pitfalls however: If your objects live in containers, every reallocation may change your objects' identity and if you allow copying of your objects, then objects returned from some function may have been created at the same address.
  • If you need a more global uniqueness, for instance because you are dealing with communicating programs or data that is persistent, use GUIDs/UUIds, such as boost.uuid.
  • You could create unique integers from some static counter, but beware of the pitfalls:
    • Make sure your increments are atomic
    • Protect against copying or create your custom copy constructors, assignment statements.

Personally, my choice has been UUIDs whenever I can afford them, because they provide me some ease of mind, not having to think about all the pitfalls.

Upvotes: 18

Luchian Grigore
Luchian Grigore

Reputation: 258548

If the objects need to be uniquely identified, you can generate the unique id in the constructor:

struct Obj
{ 
   int _id;
   Obj() { static int id = 0; _id = id++; }
};

You'll have to decide how you want to handle copies/assignments (same id - the above will work / different id's - you'll need a copy constructor and probably a static class member instead of the static local variable).

Upvotes: 12

Audrius Meškauskas
Audrius Meškauskas

Reputation: 21728

It does not look like a bad idea to use the object address as the unique (for this run) identifier, directly. Why to cast it into integer? Just compare pointers with ==:

MyObject *obj1, *obj2;
...
if (obj1 == obj2) ...

This will not work, of course, if you need to write IDs to database or the like. Same values for pointers are possible between runs. Also, do not overload comparison operator (==).

Upvotes: 0

Sergei Nikulov
Sergei Nikulov

Reputation: 5110

If you need unique id for distributed environment use boost::uuid

Upvotes: 0

Crog
Crog

Reputation: 1170

If your object is a class then you could have a static member variable which you intestinal to 0. Then in the constructor you store this value into the class instance and increment the static variable:

class

Indexed
{
public:
   Indexed() :
       m_myIndex( m_nextIndex++ )
   { }

   int getIndex() const
   { return m_myIndex; }

private:
   const int m_myIndex;
   static int m_nextIndex;
};

Upvotes: 0

Related Questions