How do I create and use a class arrow operator?
Solution 1
The operator -> is used to overload member access. A small example:
#include <iostream>
struct A
{
void foo() {std::cout << "Hi" << std::endl;}
};
struct B
{
A a;
A* operator->() {
return &a;
}
};
int main() {
B b;
b->foo();
}
This outputs:
Hi
Solution 2
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\n";
return &*r;
}
private:
PointerToString & r;
};
PointerToString(const string &s) : a(s) {}
PtPtS operator->()
{
std::cout << "arrow dereference\n";
return *this;
}
string &operator*()
{
std::cout << "dereference\n";
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 whichoperator->()
is a unary postfix operator. However, there is no new syntax introduced, so a member name is still required after the->
Solution 3
class T {
public:
const memberFunction() const;
};
// forward declaration
class DullSmartReference;
class DullSmartPointer {
private:
T *m_ptr;
public:
DullSmartPointer(T *rhs) : m_ptr(rhs) {};
DullSmartReference operator*() const {
return DullSmartReference(*m_ptr);
}
T *operator->() const {
return m_ptr;
}
};
Codesmith
Computer Programmer, Game Developer, Web Developer, Graphic Designer, IT HTML, CSS, JS, PHP, Python, C++
Updated on June 07, 2020Comments
-
Codesmith over 3 years
So, after researching everywhere for it, I cannot seem to find how to create a class arrow operator, i.e.,
class Someclass { operator-> () /* ? */ { } };
I just need to know how to work with it and use it appropriately. - what are its inputs? - what does it return? - how do I properly declare/prototype it?
-
Codesmith over 12 yearsdoes the arrow operator also work to return structure members as it does class members?
-
Darryl over 12 yearsIt can return struct members just as easily as it can return class members. What happens when you use the arrow is determined by the body of the operator->() member function. The line "return &a;" can be changed to return whatever you decide is appropriate.
-
Sebastian Redl over 8 yearsThere is no way this code compiles on a decent compiler.
-
Daniel Gallagher over 8 years@SebastianRedl, you are correct. I've updated the explanation and example so that it does compile.
-
alfC over 6 yearsIt is not that easy,
return_type{}->()->()->() ... ->()
has to be a pointer for this to be a valid code. -
metablaster over 3 yearsInteresting, but what's the point of unneeded indirections? why not just returning reference of underlying object? (reference of
string a
in your case). Why making simple things complicated? I would downvote you for complicating, but first there must be a reason for your approach.