W_K
W_K

Reputation: 33

how to generate a unique id for each instance within a class in c++?

I have attempted to create unique id's for all instances in my class, but this seems to be leading to errors later when trying to compile the program. this is the code i have written for the classes:

//this is GameObject.h
class GameObject
{
public:

    int instances;
    GameObject();
    void Display();
protected:
    int id;
};

//this is GameObject.cpp
#include "GameObject.h"
#include <iostream>

using namespace std;


GameObject::GameObject()
{
    instances = this->id; //is this the correct way to generate the unique id?

}

Upvotes: 3

Views: 9465

Answers (3)

John Zwinck
John Zwinck

Reputation: 249552

Do something like this:

class GameObject
{
public:
    int id;
    GameObject() : id(++s_id) {}
protected:
    static std::atomic<int> s_id;
};

// in the .cpp file:
std::atomic<int> GameObject::s_id;

This way, each object constructed will get the next id, starting from 1 (because the static will be initialized to zero by default). It probably doesn't matter what value you start from. You might want to take care when writing copy constructors, assignment operators, and the like. Finally, note that the atomic type is part of C++11; if you don't have support for it you can say "boost" instead of "std" there. Either version will give you thread safety, in case you need it.

Upvotes: 6

hmjd
hmjd

Reputation: 122001

No, each instance of GameObject will have its own (uninitialized) instance of id. There needs to be a shared incrementing id instance available to all instances of GameObject. One mechanism to achieve this to use a static class variable. If threads are involved you need to synchronize access to the static variable:

class GameObject
{
protected:
    static int id;
};

int GameObject::id; // defaults to zero and should be added to
                    // exactly one .cpp file only.

GameObject::GameObject() : instances(GameObject::id++) {}

Another alternative is to use boost::uuid:

#include <string>
using std::string;

#include <boost/lexical_cast.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
using boost::lexical_cast;
using boost::uuids::uuid;
using boost::uuids::random_generator;

class GameObject
{
public:
    string instances;
    GameObject() : instances(make_uuid_());
    void Display();
private:
    string make_uuid_()
    {
        return lexical_cast<string>((random_generator())());
    }
};

Upvotes: 4

Alok Save
Alok Save

Reputation: 206616

This is not correct because id merely has an indeterminate value(since it is uninitialized) not unique value.

You could address of an object as the unique identifier. Each object in C++ is placed at an different address. However, if you need to identify each object this way there is something amiss in your design.

Upvotes: 2

Related Questions