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*?