Overloading arrow operator from a pointer object

Started by
3 comments, last by mychii 5 years, 7 months ago

Hi, now my curiosity is stuck on arrow operator. Is there a way to overload an arrow operator from a pointer object? If none, what's the reason that this isn't allowed? or is there a correct/better approach?


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

class A
{
public:
	B* b;

	B* operator->()
	{
		return b;
	}
};

int main()
{
	A a;
	a->foo(); // Works.

	A* pa = new A();
	(pa->operator->())->foo(); // Works.

	pa->foo(); // Doesn't work as it refers directly to A's foo() which doesn't exist instead of triggering operator->() first.

	return 0;
}

Cheers. ?

Advertisement

You may already know this, but typically you'd just write:


(*pa)->foo();

This might be the 'correct/better' approach you asked about. It's idiomatic and concise, and conforms to the semantics of the language (assuming the overload does something sensible, of course).

To the best of my knowledge, C++ requires that overloaded operators have at least one operand of a user-defined type. Even if you could do what you're asking about though, it seems like it would be obfuscatory and would violate the principle of least surprise, and that there would probably be better ways of accomplishing whatever you were trying to accomplish.

12 hours ago, mychii said:

Hi, now my curiosity is stuck on arrow operator. Is there a way to overload an arrow operator from a pointer object? If none, what's the reason that this isn't allowed?

The arrow operator automatically chains, and this is by design. It enables proxy objects like iterators to work correctly.

That is, for any series of derived classes and overloaded -> operators the compiler will automatically advance until it hits the built-in operator of the final pointed-to object. For a chain, pA->foo() would automatically expand to:  pA.operator->().operator->().operator->() ... .operator->()->foo(), expanding as many times as needed until it hits the final actual object.

 

The dot operator desn't chain and cannot be overloaded. You can probably use that to get what you need.  Also if necessary you can specify the scope of the function you need, although it is easy to invoke undefined behavior through misuse.

 

Alrite, thanks for the info guys!

@Zakwayda Actually I forgot to put the dereferenced example, but yes I know about it, thanks for the reminder.

This topic is closed to new replies.

Advertisement