0

I want to create an unique id for each instance of a class, that cannot be modified. Then I want to create an operator == such that p1==p2 returns true if p1 and p2 have the same id, i.e. are the same element. The way I plan to do it is:

parent.hpp

class parent{
    public:
        ...
        int parent::GetUid() const;

    private:
        static int newUID;
        const int uid;

}

parent.cpp

bool operator ==(const parent p1, const parent p2)
{
    return (p1.GetUid()== p2.GetUid());
}

parent::parent()
:uid(newUID++){}


int parent::newUID=0;

int parent::GetUid() const
    {
        return uid;
    }

But though I do initialize newUID, I get the following error:

error c2789 an object of const-qualified type must be initialized

EDIT: the above error is solved and occurred because of a typo I made.

Now when I try to use the operator I get the following error:

error C2676: binary '==' : 'parent' does not define this operator or a conversion to a type acceptable to the predefined operator

I get this error when I do the following:

parent p1;
parent p2;
...
if(p1==p2){
    t=0;
}
astudentofmaths
  • 1,122
  • 2
  • 19
  • 33

2 Answers2

1

Why not just use the address of each parent ?

bool operator == (const parent &p1, const parent &p2)
{
    return &p1 == &p2;
}
Sid S
  • 6,037
  • 2
  • 18
  • 24
  • Would not preserve the ID through moves or or storage in most library containers. – user4581301 Jan 05 '18 at 00:46
  • That's not a part of the problem description. He stated that each instance has a unique ID. – Sid S Jan 05 '18 at 01:06
  • Have to disagree with that read of intent. If I had an object with a known identifier I would not expect or want that identifier to change because another object was removed from a `vector`. You can't count on it as an identifier anymore. – user4581301 Jan 05 '18 at 01:37
  • @user4581301 You're assuming that he will keep the instances in a container, *and* keep pointers to individual elements ? – Sid S Jan 05 '18 at 01:41
1

It should at least compile if you write parent::parent() :uid(newUID++){}. Note, however, that you have to do some more work to tackle the idea of "identity" that way. First, newUID++ is not thread safe, so you could create different object with the same "identity". Then, you have to provide a copy constructor unless you want to allow that the same "identity" may be represented by different objects in memory.

Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
  • Thank you for the typo. What do you mean by "trade safe" ? Indeed, I did not think about the copy constructor, thanks. – astudentofmaths Jan 05 '18 at 00:57
  • @Arthurim I don't see the phrase "trade safe" anywhere in the answer, can you elaborate on what you are asking about? I can see "thread safe" in the answer, and thread safety is whole other topic: [What is meant by “thread-safe” code?](https://stackoverflow.com/questions/261683/what-is-meant-by-thread-safe-code). – Algirdas Preidžius Jan 05 '18 at 01:15
  • `newUID++` is not an atomic operation; it consists of "read the value of `newUID`" and "increment the value of `newUID`". When two threads create `parent`-objects concurrently, both threads might both perform the "reading"-part before the other has reached the "incrementing"-part, respectively. So two threads might assign the same `uid`. That's why it is not thread-safe. Use a `mutex` or `std::atomic`. Of course - thread-safety only matters if you are in a multithreaded environment, i.e. if your program spawns multiple threads.... – Stephan Lechner Jan 05 '18 at 01:29
  • Mea Culpa, I meant to write "thread" and not "trade". Thank you, I understand this better. I am not doing any multithreading here and the user won't be neither. However, I still have a compiler error when using the operator, see my edited question. – astudentofmaths Jan 05 '18 at 02:06