Systems CourseC/C++ · Linux · Memory
C++ CoreLesson 42 of 441 min read6 questions

The Arrow Operator

ptr->member is shorthand for (*ptr).member — and you can overload it.

Test yourself ↓

Concept core idea Watch out easy to get wrong

Concept

Key concepts

  1. ptr->member is shorthand for (*ptr).member — dereference the pointer, then apply the dot.
  2. . is used on an object (or reference); -> on a pointer (raw or smart).
  3. For a raw pointer, -> is built-in. For your own class you can overload operator-> — that's how smart pointers and iterators work.
  4. An overloaded operator-> returns a pointer; the compiler then applies the real -> to it (and keeps chaining until it reaches a raw pointer).
  5. That's why unique_ptr/shared_ptr let you write p->method() even though p is an object, not a raw pointer.
  6. (Curiosity: -> through a null-cast pointer is the trick behind offsetof for a member's byte offset — don't use it in real code.)

Raw pointer, and a custom operator->

C++
struct Entity {
    int a;
    void print() const { std::cout << a; }
};

// raw pointer
Entity* e = new Entity{5};
(*e).a = 10;    // the long way
e->a   = 10;    // shorthand — identical
e->print();
delete e;

// custom operator-> (a mini smart pointer)
class Wrapper {
    Entity* ptr;
public:
    Wrapper(Entity* p) : ptr(p) {}
    Entity* operator->() { return ptr; }   // overloaded arrow returns a pointer
};
Wrapper w(new Entity{5});
w->print();     // w.operator->()->print()
Watch out

Easily confused

. vs ->
. on an object/reference. -> on a pointer (raw or smart); p->m == (*p).m.
built-in -> vs overloaded ->
Raw pointer: -> is built-in. Custom class (smart pointer / iterator): you overload operator->, which returns a pointer.

Test yourself

6 questions on this lesson. Write your answers from memory, then compare them with the model answers side by side.