Оператор разыменования (*
) перегрузка работает как любая другая перегрузка оператора. Если вы хотите изменить значение разыменования, вам нужно вернуть неконстантную ссылку. Таким образом, *sp = value
фактически изменит значение, на которое указывает sp.pData
, а не временное значение, сгенерированное компилятором.
Оператор разукрупнения структуры (->
) Перегрузка - это особый случай перегрузки оператора. Оператор фактически вызывается в цикле до тех пор, пока не будет возвращен реальный указатель, а затем этот реальный указатель будет разыменован. Я предполагаю, что это был единственный способ, которым они могли придумать, чтобы реализовать его, и это оказалось немного хаки. Однако у него есть некоторые интересные свойства. Предположим, вы имели следующие классы:
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; }
};
Если у вас объект d
типа D
, вызывая d->bar
бы сначала вызвать D::operator->()
, затем C::operator->()
, а затем B::operator->()
, который, наконец, возвращает реальный указатель на структуру A
, и его bar
Элемент разыменовывается обычным образом. Следует отметить, что в следующем:
struct E1 {
int foo, bar;
E1 operator->() { return *this; }
};
Вызов e->bar
, где e
имеет тип E1
, производит бесконечную петлю. Если вы хотите на самом деле разыменовать e.bar
, вам нужно будет сделать это:
struct E2 {
int foo, bar;
E2 *operator->() { return this; }
};
Резюмируя:
- При перегрузке оператора разыменования, тип должен быть
T&
, потому что это необходимо изменить значение, на которое указывает pData
.
- При перегрузке разыменования структуры тип должен быть
T*
, потому что этот оператор является особым случаем, и именно так оно и работает.
'* p = 2' часто желаемый синтаксис. Было бы обидно, если бы он ничего не сделал. – chris
Люди обычно, по крайней мере, пытаются подделать согласованность с перегрузками. C++ 11 5.3.1p1 [expr.unary.op] выдает оператор '*' для типов указателей, и его не редкость имитировать (включая перегрузки для 'const', если вы хотите запустить полный гамбит). – WhozCraig