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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…