Archived

This topic is now archived and is closed to further replies.

Overloading the -> operator...

This topic is 5119 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Every time I see the -> operator overloaded (like with safe pointers), it ends up returning the object (which is a pointer) that the safe pointer is representing. Sorry if that doesn't make sense, but what I mean is, if the safe pointer is hiding a pointer to a CObj , it will return it when the -> operator is called. My question is: why? If you return the pointer, I don't see how the member function/variable you are trying to access gets accessed. For example:
SafePointer->SomeFunction();
//...becomes...
pHiddenObj SomeFunction();
    
I don't see how the some funtion is accessed. [edited by - PlayGGY on December 12, 2003 8:39:59 PM] [edited by - PlayGGY on December 12, 2003 8:40:13 PM] [edited by - PlayGGY on December 12, 2003 8:47:56 PM]

Share this post


Link to post
Share on other sites
Think of the -> operator as a "defer" operator. The compiler keeps applying operator overloading on the lhs until it's left with a pointer type.

Watch:


class A
{
public:
B &operator->() { return myB; }
B myB;
};

class B
{
public:
C* operator->() { return &myC; }
C myC;
}

class C
{
public:
void foo();
};

Now I can do:

A myA;
A->foo();

When the compiler sees me applying -> to A, which is not a pointer type, it inserts the A::operator-> call. Now it has -> being applied to a B, which isn't a pointer either. So it applies B::operator->. Now it has C*, which is a pointer type. So it does the built-in arrow action.

This is very useful for implementing smart pointers.

For more information, see Stroustrup, The Design and Evolution of C++.


"Sneftel is correct, if rather vulgar." --Flarelocke

[edited by - sneftel on December 12, 2003 8:35:40 PM]

Share this post


Link to post
Share on other sites
"Think of the -> operator as a "defer" operator. The compiler keeps applying operator overloading on the lhs until it''s left with a pointer type."

I am probably missunderstanding you, but I thought if an operator was overloaded, it simply did exactly as your operator''s definition said. But what you are saying is that is will keep trying to get a pointer, right? If that is what you are saying, why can''t you just go:
pObj SomeFunction();


I know that you know what you are saying, I just don''t understand it.

Share this post


Link to post
Share on other sites
quote:
Original post by PlayGGY
I am probably missunderstanding you, but I thought if an operator was overloaded, it simply did exactly as your operator's definition said. But what you are saying is that is will keep trying to get a pointer, right? If that is what you are saying, why can't you just go:
pObj SomeFunction();


Right. But your function is in charge of deciding what *kind* of pointer it'll get. This lets you pretend that a class is actually a pointer to an object of another class.

Here: a rudimentary smart pointer class. It's similar to auto_ptr.
The only way in which it is "smart" is that it deletes its pointed-to object when it itself is destroyed.


template<typename T>
class MySmartPtr
{
public:
MySmartPtr(T* init) { ptr = init; }
~MySmartPtr() { delete ptr; }
T& operator*() { return *ptr; }
T* operator->() { return ptr; }
private:
T* ptr;
};

MySmartPtr<string> stringPtr(new string);
stringPtr->resize(3); // resizes the pointed-to string






"Sneftel is correct, if rather vulgar." --Flarelocke

[edited by - sneftel on December 12, 2003 8:54:01 PM]

Share this post


Link to post
Share on other sites
After looking at what you quoted, I think you missunderstood me. I meant "Why aren't these two lines identical if the -> returns the pointer contained by a safe pointer?"

pObj->SomeFunction(); //The -> returns a pOtherObj, lets say
pOtherObj SomeFunction();


What makes those lines different? If a function is called, like an overloaded operator, it executed the function, and continues evaluating the original statement with the return value of the function, if any, right?

[edited by - PlayGGY on December 12, 2003 9:19:43 PM]

Share this post


Link to post
Share on other sites
Well, first off, you''re calling that first line "pObj". That leads me to believe that in your code fragment, "pObj" is a pointer. (it''s a good idea to write those things out in example code.) Just to make it clear: the overloaded arrow operator is not invoked when you actually have a real pointer.

Assuming that pObj is NOT a pointer, however, the two lines both end up invoking OtherObj::SomeFunction(). Of course, they do it on different objects of class OtherObj.


"Sneftel is correct, if rather vulgar." --Flarelocke

Share this post


Link to post
Share on other sites
I think I see how you are getting confused. You are right that when you overload most operators, you can make them do whatever you want, just as if they were plain old functions with funny names and weird syntax.

But the -> operator is a special case. The compiler does extra stuff when you use it, even when you overload it. "SafePointer->SomeFunction()" does NOT become "pHiddenObj SomeFunction()", it becomes "pHiddenObj->SomeFunction()";

Share this post


Link to post
Share on other sites
quote:
Original post by Sneftel
Well, first off, you''re calling that first line "pObj". That leads me to believe that in your code fragment, "pObj" is a pointer. (it''s a good idea to write those things out in example code.) Just to make it clear: the overloaded arrow operator is not invoked when you actually have a real pointer.

Assuming that pObj is NOT a pointer, however, the two lines both end up invoking OtherObj::SomeFunction(). Of course, they do it on different objects of class OtherObj.


"Sneftel is correct, if rather vulgar." --Flarelocke



Woah... that explains alot!

I wasn''t thinking at all, yikes... I wasn''t thinking that the default operation for the -> oeprator would be called instead of the overloaded one... sorry for all of that!

But I was suprised when you said those two lines both call SomeFunction... I just tried it, and it doesn''t, you need to have an access operator, like ''.'' or ''->''. But thanks a lot for explaining that the default -> is called... wow, that really would have screwed my up.

Share this post


Link to post
Share on other sites
quote:
Original post by pinacolada
I think I see how you are getting confused. You are right that when you overload most operators, you can make them do whatever you want, just as if they were plain old functions with funny names and weird syntax.

But the -> operator is a special case. The compiler does extra stuff when you use it, even when you overload it. "SafePointer->SomeFunction()" does NOT become "pHiddenObj SomeFunction()", it becomes "pHiddenObj->SomeFunction()";

That''s right. See, "SomeFunction()" is not a parameter passed to the "->" operator. The "->" operator returns an object, and whatever''s to the right of the operator is acted on the object.

So for a non-overloaded -> operator, this:

pObject->SomeFunction( );

is equivalent to:

(*pObject).SomeFunction( );

In an overloaded -> operator, this:

Object->SomeFunction( );

is like:

(Object.operator->()).SomeFunction( );

So the user-defined operator "->" returns the object, instead of the compiler dereferencing pObject to get it.

~CGameProgrammer( );

-- Post screenshots of your projects. 100+ posts already in the archives.

Share this post


Link to post
Share on other sites
The last two replies from pinacolada and CGameProgrammer explained it! All three of you thanks alot!

[edited by - PlayGGY on December 12, 2003 11:35:45 PM]

Share this post


Link to post
Share on other sites
i was always told by my comp sci profs that it's a bad thing to overload the -> operator because it gets really messy and it usually thought of as "bad" style along with the & operator and a few others so you should avoid them if possible

[edited by - Hexxagonal on December 13, 2003 1:58:23 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by Hexxagonal
i was always told by my comp sci profs that it''s a bad thing to overload the -> operator because it gets really messy and it usually thought of as "bad" style along with the & operator and a few others so you should avoid them if possible

Personally I strongly disagree; operator overloading should always be done responsibly (giving operators unexpected semantics is terribly confusing and worse by far than having to type out function calls), but used properly, they can make things much clearer. In the case of operator->, it makes perfect sense (as has been pointed out) to overload it when designing smart pointer classes, for instance, allowing smart pointers to be used in the same fashion as built-in ones.

Share this post


Link to post
Share on other sites