I define a class to wrap raw pointer, so the pointer can be delete automatically. Here is my code
#include <iostream>
class Entity
{
private:
std::string e_name;
public:
Entity():e_name("unknown"){}
void whoami() {
std::cout << e_name;
}
};
class ScopePointer
{
private:
Entity *_e;
public:
ScopePointer(Entity *e) : _e(e) {}
~ScopePointer() { delete _e; }
Entity *operator->() { return _e; }
};
int main(int argc, char *argv[])
{
ScopePointer p(new Entity());
p->whoami();
}
It works well but I quite don't understand how p->whoami();
works.
I mean the operator -> overload in ScopePointer should work like below
p.operator->()->whoami();or p->->whoami();
the first ->
should return Entity* and the next ->
call class method.
why only one -> can make it work ?
CodePudding user response:
I hope that this quote from the C 14 Standard will help to understand how the operator works.
The C 14 Standard (13.5.6 Class member access, p #1)
An expression x->m is interpreted as (x.operator->())->m for a class object x of type T if T::operator->() exists and if the operator is selected as the best match function by the overload resolution mechanism.
So the overloaded operator in fact is a "prefix expression" of the built-in operator-> that supplies a pointer used in the built-in operator.
CodePudding user response:
I quite don't understand how
p->whoami();
works
There is an exception to the ordinary rules of operators for ->
, such that you only need one ->
. The language requires the implementation recursively evaluate operator->
until it finds a pointer object, instead of a object of some class type.
From [over.ref]
A class member access operator function is a function named
operator->
that is a non-static member function taking no parameters. For an expression of the formpostfix-expression->templateoptid-expression
the operator function is selected by overload resolution ([over.match.oper]), and the expression is interpreted as
(postfix-expression.
operator->()
) -> templateopt id-expression