The arrow operator has no inputs. Technically, it can return whatever you want, but it should return something that either is a pointer or can become a pointer through chained ->
operators.
The ->
operator automatically dereferences its return value before calling its argument using the built-in pointer dereference, not operator*
, so you could have the following class:
class PointerToString
{
string a;
public:
class PtPtS
{
public:
PtPtS(PointerToString &s) : r(s) {}
string* operator->()
{
std::cout << "indirect arrow
";
return &*r;
}
private:
PointerToString & r;
};
PointerToString(const string &s) : a(s) {}
PtPtS operator->()
{
std::cout << "arrow dereference
";
return *this;
}
string &operator*()
{
std::cout << "dereference
";
return a;
}
};
Use it like:
PointerToString ptr(string("hello"));
string::size_type size = ptr->size();
which is converted by the compiler into:
string::size_type size = (*ptr.operator->().operator->()).size();
(with as many .operator->()
as necessary to return a real pointer) and should output
arrow dereference
indirect dereference
dereference
Note, however, that you can do the following:
PointerToString::PtPtS ptr2 = ptr.operator->();
run online: https://wandbox.org/permlink/Is5kPamEMUCA9nvE
From Stroupstrup:
The transformation of the object p into the pointer p.operator->()
does not depend on the member m pointed to. That is the sense in which operator->()
is a unary postfix operator. However, there is no new syntax introduced, so a member name is still required after the ->
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…