a question about operator overloading

  • Thread starter Thread starter Abubakar
  • Start date Start date
A

Abubakar

Hi all,
I downloaded a code (a c++ project) over the internet and at one place I saw
the following lline:

// allow usage as a pointer.
operator CMemDC*() { return this; }

(the comment up there was written in the source)

CMemDC is the class name.

I dont understand what it does, and so I dont know what is its use and whats
going on here basically. So somebody plz explain me what does this mean and
what r the benefits ?

Regards,

-ab.
 
Hi all,
I downloaded a code (a c++ project) over the internet and at one place I saw
the following lline:

// allow usage as a pointer.
operator CMemDC*() { return this; }

(the comment up there was written in the source)

CMemDC is the class name.

I dont understand what it does, and so I dont know what is its use and whats
going on here basically. So somebody plz explain me what does this mean and
what r the benefits ?

That's an MFC-ism and shouldn't be emulated. To understand why someone
might have done this 15 years or so ago, consider that in many places, MFC
uses temporary objects to wrap Windows handles such as HDC, HWND, etc, and
those temporary objects are represented by pointers. Thus, it seemed
desirable to define various member functions in terms of pointers rather
than references, even though the argument is required and should have been
a reference. This allowed a function f to take, say, a CDC*, and you could
call it with f(x) instead of f(*x), assuming x was a CDC* or a pointer of a
type derived from CDC. As long as you're dealing solely with pointers, this
works OK, but to use a class like CMemDC, you have to create an object
yourself, because MFC doesn't deal in temporary CMemDC objects. Usually
CMemDC objects are local or member variables, and it makes sense to define
them as objects, rather than pointers you have to initialize with new. But
to call the aforementioned f on a CMemDC named x, you have to say f(&x),
and the MFC designers didn't like that. This led them to define the
conversion function, spelled "operator CMemDC*()", which allows you to say
f(x). This is a minor convenience at best, and as people became more
familiar with C++, it became apparent that conversion functions are the
source of many errors, so hardly anyone would write code such as this
today. I think it's better to use references for required function
parameters than pointers, and that's what I do in my MFC code when
possible; I find I can live with having to say f(*x), and sometimes I'll
even bind a local reference variable y to *x, so I can say f(y) and y.g()
instead of y->g().
 
Abubakar said:
Hi all,
I downloaded a code (a c++ project) over the internet and at one place I saw
the following lline:

// allow usage as a pointer.
operator CMemDC*() { return this; }

(the comment up there was written in the source)

CMemDC is the class name.

I dont understand what it does, and so I dont know what is its use and whats
going on here basically. So somebody plz explain me what does this mean and
what r the benefits ?

A short example will illustrate this better:

class A {
public:
int nyah;
// operator A*() { return this; }
};

Now let's say you have this method:

void nyah8(A* pa) {
pa->nyah = 8;
}

With that operator A*() above commented, the only way for you to call
nyah8 is by passing it the address of an A object explicitly, e.g.:

A a;
nyah8(&a);

However, the existence of this:

operator A*() { return this; }

Basically says "if you find a context where a pointer to A is needed,
call this method", which in this case, returns a pointer to itself.

I'd say this is a bad, bad practice though. A good place to use this
would be if your class is actually wrapping a pointer (say, CAutoPtr in
ATL). Then it's legit to have an operator T*() to return the pointer
you're wrapping, so your pointer-wrapping class can be used where raw
pointers are expected.

But using it just to shortcut typing & in front of your object when
calling functions that expect pointers is bad form, IMO.
 
I'd say this is a bad, bad practice though. A good place to use this would
be if your class is actually wrapping a pointer (say, CAutoPtr in ATL).
Then it's legit to have an operator T*() to return the pointer you're
wrapping, so your pointer-wrapping class can be used where raw pointers
are expected.

Having an operator T* is only half the solution for a pointer class. The
really important part is the

T& operator*()

which allows you to use -> member access
 
I'd say this is a bad, bad practice though. A good place to use this
would be if your class is actually wrapping a pointer (say, CAutoPtr in
ATL). Then it's legit to have an operator T*() to return the pointer
you're wrapping, so your pointer-wrapping class can be used where raw
pointers are expected.

Just be aware that blurring the identities of the wrapper and the thing
wrapped tends to create potential problems. For example, operator T* allows
the object to be used with the array syntax and converted to void*. This is
not as bad as CComPtr overloading operator& to return the address of the
raw pointer, but still, it's hard to argue against defining a member
function such as auto_ptr's "get" instead of the conversion function.
 
Back
Top