Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can operator-> be overloaded manually?

Wouldn't it make sense if p->m was just syntactic sugar for (*p).m? Essentially, every operator-> that I have ever written could have been implemented as follows:

Foo::Foo* operator->()
{
    return &**this;
}

Is there any case where I would want p->m to mean something else than (*p).m?

like image 515
fredoverflow Avatar asked May 30 '10 12:05

fredoverflow


People also ask

How does -> operator overload work?

The operator-> has special semantics in the language in that, when overloaded, it reapplies itself to the result. While the rest of the operators are applied only once, operator-> will be applied by the compiler as many times as needed to get to a raw pointer and once more to access the memory referred by that pointer.

Can -> be overloaded in C++?

The class member access operator (->) can be overloaded but it is bit trickier. It is defined to give a class type a "pointer-like" behavior. The operator -> must be a member function. If used, its return type must be a pointer or an object of a class to which you can apply.

Why are operators overloaded?

The purpose of operator overloading is to provide a special meaning of an operator for a user-defined data type. With the help of operator overloading, you can redefine the majority of the C++ operators. You can also use operator overloading to perform different operations using one operator.

Why we Cannot overload operators?

These operators cannot be overloaded because if we overload them it will make serious programming issues. For an example the sizeof operator returns the size of the object or datatype as an operand. This is evaluated by the compiler. It cannot be evaluated during runtime.


1 Answers

operator->() has the bizarre distinction of implicitly being invoked repeatedly while the return type allows it. The clearest way to show this is with code:

struct X {
    int foo;
};

struct Y {
    X x;
    X* operator->() { return &x; }
};

struct Z {
    Y y;
    Y& operator->() { return y; }
};

Z z;
z->foo = 42;          // Works!  Calls both!

I recall an occasion when this behaviour was necessary to enable an object to behave as a proxy for another object in a smart-pointer-like context, though I can't remember the details. What I do remember is that I could only get the behaviour to work as I intended using the a->b syntax, by using this strange special case; I could not find a way to get (*a).b to work similarly.

Not sure that this answers your question; really I'm saying, "Good question, but it's even weirder than that!"

like image 139
j_random_hacker Avatar answered Oct 06 '22 02:10

j_random_hacker