Tuesday, January 29, 2008

C++ overloading operator& ( Or Find the addess of a object)

Recently a friend of mine ( name : rejeesh ) asked me "how to find the address of an object if the & operator is  overloaded" ?

Example class is like this

class AddressBlocker


  operator &()  {  return 0;  }

so if you try to execute a code like this

AddressBlocker op;
AddressBlocker* Pt = &op;

Pt will be NULL. Pt =  &op will not pass the  real address of op to Pt. Because the operator is overloaded.

So how to get the address ??

When he asked me it, i found two solutions with templates .  One deriving a new class from the required class , and the second one is
more tricky. I will explain ( by showing the code) here both two methods.

Method 1.

template<typename T>
class Addressfinder : public T
    Addressfinder* operator&() { return this; }

and you use it like this

Addressfinder<AddressBlocker>& finder = static_cast<Addressfinder<AddressBlocker>&> ( blockMe );

and address can be retrieved by simple  "AddressBlocker* pValid = &finder;" . This will work since i overloaded the &operator in Addressfinder class.
Method 2.

I think this is more good compared to the above. Since it is not creating any more relationships with the classes. and also no need for casting to use it.

template <typename T>
class AddressfinderII
    T& tOb;
    AddressfinderII(T& t): tOb(t){}
    T * operator&()
        return reinterpret_cast<T*> ( *reinterpret_cast<int *>( this ) );

usage is like this

AddressBlocker blocker;
AddressfinderII<AddressBlocker> finderII(blocker);AddressBlocker * pAddress = &finderII;

if you look the size of this class , it just 4 bytes. because storing reference is same as pointer.
The class object's memory will have just the real address of object. And i extracted that value in operator& and returned.

Ok.. There is a more convenient way , he told me . and it is used in boost libraries. anyway i could find some alternatives 

Method 3

template<typename T>
T* addessof(T& t)
    return reinterpret_cast<T*>(& reinterpret_cast<int&> ( t ) );

and can be use like addressof( blocker); it is more convenient. it has similarities with method 1. So now no more address hiding..

No comments: