TRICK: Unique ID'ing

P

Peter Oliphant

Sometimes it's hard to get straight when passing or storing or returning an
instance of a class whether you are still dealing with the original object
or a copy. For example, the '=' operator used on pointers to two instance of
a class can be overloaded to return the pointer to the target instance or a
pointer to a copy of the target instance. When passing an instance of a
class it can be done so the method will manipulate the instance itself
(reference) or a copy of the instance (value). Implicit copy constructing
can also confuse things. The '==' operator can be overloaded to return true
only if the two instances are the same instance, or it can return true when
the two merely have the same value (e.g., two long variables when compared
for equality will return if they have the same value, not if they are the
same variable). So it's not always obvious if one is manipulating the object
desired or a copy of the object.

To combat this, I use the following technique, which could be called 'unique
ID'ing'. Here is reduced coded to show how it works:

class MyClass
{
public:
MyClass( ) { m_Init() ; }
~MyClass( ) {}

public:
long ID( ) { return m_ID ; }

private:
void m_Init( )
{
m_ID = ++s_ID ;
}

private:
long m_ID ;
static long s_ID = 0 ;
} ;

Since 's_ID' is static it is a single variable which will be used by all
instances of the class created. The m_Init( ) (which needs to be put in
every constructor) will increment this static variable and then store it's
new value in the instance's personal copy of 'm_ID'. Thus, 'm_ID' is unique
for each instance created!

Now if you have an instance of MyClass that you suspect might be a copy of
the intended instance, just keep track of ID of the instance you want (via
ID( )) and compare it against the suspect. If it matches you know they are
the same object. If not, you know they aren't!

There is a side bonus to this. If you examine the value of 's_ID' it will
tell you exactly how many instances of MyClass have been created so far in
the application run! Thus, one can better discover situations where copies
are being created which are unintended...

There might be other ways of doing this, possibly even built into the
system, but I still think this is a cool trick... : )

[==P==]
 
C

Carl Daniel [VC++ MVP]

Peter said:
Sometimes it's hard to get straight when passing or storing or
returning an instance of a class whether you are still dealing with
the original object or a copy. For example, the '=' operator used on
pointers to two instance of a class can be overloaded to return the
pointer to the target instance or a pointer to a copy of the target
instance. When passing an instance of a class it can be done so the
method will manipulate the instance itself (reference) or a copy of
the instance (value). Implicit copy constructing can also confuse
things. The '==' operator can be overloaded to return true only if
the two instances are the same instance, or it can return true when
the two merely have the same value (e.g., two long variables when
compared for equality will return if they have the same value, not if
they are the same variable). So it's not always obvious if one is
manipulating the object desired or a copy of the object.
To combat this, I use the following technique, which could be called
'unique ID'ing'. Here is reduced coded to show how it works:

class MyClass
{
public:
MyClass( ) { m_Init() ; }
~MyClass( ) {}

public:
long ID( ) { return m_ID ; }

private:
void m_Init( )
{
m_ID = ++s_ID ;
}

private:
long m_ID ;
static long s_ID = 0 ;
} ;

Since 's_ID' is static it is a single variable which will be used by
all instances of the class created. The m_Init( ) (which needs to be
put in every constructor) will increment this static variable and
then store it's new value in the instance's personal copy of 'm_ID'.
Thus, 'm_ID' is unique for each instance created!

Now if you have an instance of MyClass that you suspect might be a
copy of the intended instance, just keep track of ID of the instance
you want (via ID( )) and compare it against the suspect. If it
matches you know they are the same object. If not, you know they
aren't!
There is a side bonus to this. If you examine the value of 's_ID' it
will tell you exactly how many instances of MyClass have been created
so far in the application run! Thus, one can better discover
situations where copies are being created which are unintended...

There might be other ways of doing this, possibly even built into the
system, but I still think this is a cool trick... : )

Old trick.

An even easier way - just cast the this pointer to an integer type and call
that the ID. Guaranteed unique with absolutely no overhead.

-cd
 
P

Peter Oliphant

Old trick.

I figured, but old tricks are new for each individual at least once... : )

And IMHO this forum could use some more voluntarily posts of tricks and
techniques in contrast to all of the how-do-I-solve-this-problem posts. In
one case solution-posters are being pro-active, in the other
passive-aggressive. I think this forum (and others) could benefit from
both... : )
An even easier way - just cast the this pointer to an integer type and
call that the ID. Guaranteed unique with absolutely no overhead.

Cool, but this doesn't get you the added bonus of a variable which can be
used to determine if instances ar being created. For example, I can look at
's_ID', step over a routine, and if 's_ID' has increased I know instances
have been created. There are times (like this weekend for me....lol) when I
have discovered methods that were creating and manipulating copies when I
wanted to be manipulating the originals. I stepped over the 'offending'
method, and when I saw instances being created, I knew what the problem was
and where to look for them... : )

And the 'overhead' you speak of is one long per class definition, one long
per instance, one line of code, and one single-line-of-code method (ID( )).
Not exactly what I'd call 'heavy' in this day of giga-bytes and tera-bytes
of storage.

Although, granted, your solution is both elegant and sweet... : )

[==P==]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top