C++ overloading dereference operators

c++

Solution

The dereference operator (`*`) overload works like any other operator overload. If you want to be able to modify the dereferenced value, you need to return a non-const reference. This way `*sp = value` will actually modify the value pointed to by `sp.pData` and not a temporary value generated by the compiler.

The structure dereference operator (`->`) overload is a special case of operator overloading. The operator is actually invoked in a loop until a real pointer is returned, and then that real pointer is dereferenced. I guess this was just the only way they could think of to implement it and it turned out a bit hackish. It has some interesting properties, though. Suppose you had the following classes:

struct A {
    int foo, bar;
};

struct B {
    A a;
    A *operator->() { return &a; }
};

struct C {
    B b;
    B operator->() { return b; }
};

struct D {
    C c;
    C operator->() { return c; }
};

If you had an object `d` of type `D`, calling `d->bar` would first call `D::operator->()`, then `C::operator->()`, and then `B::operator->()`, which finally returns a real pointer to struct `A`, and its `bar` member is dereferenced in the normal manner. Note that in the following:

struct E1 {
    int foo, bar;
    E1 operator->() { return *this; }
};

Calling `e->bar`, where `e` is of type `E1`, produces an infinite loop. If you wanted to actually dereference `e.bar`, you would need to do this:

struct E2 {
    int foo, bar;
    E2 *operator->() { return this; }
};

To summarize:

- When overloading the dereference operator, the type should be `T&` because that is necessary to modify the value pointed to by `pData`.

- When overloading the structure dereference, the type should be `T*` because this operator is a special case and that is just how it works.

Problem

I'm relatively new to C++, still trying to get a hang of the syntax. I've been taking a look at a few operator overloading examples, most recently smart pointer implementations. Here's a really generic example I'm looking at: ``` template < typename T > class SP { private: T* pData; // Generic pointer to be stored public: SP(T* pValue) : pData(pValue) { } ~SP() { delete pData; } T& operator* () { return *pData; } T* operator-> () { return pData; } }; ``` When overloading the dereference operator why is the type T&? Similarly, when overloading the structure dereference why is the type T*?

Original source

Related problems