• ### Popular Now

• 13
• 18
• 19
• 27
• 10

#### Archived

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

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

## 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 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.

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

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

##### 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 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 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 saypOtherObj 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 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 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 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 on other sites
quote:
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.