Если у меня есть указатель на объект, который имеет перегруженный нижний оператор ([]
) почему не может я делать это:
MyClass *a = new MyClass();
a[1];
но должны сделать это вместо этого:
MyClass *a = new MyClass();
(*a)[1];
Это потому, что вы не можете перегрузить операторы для типа указателя; вы можете перегрузить только оператор, у которого хотя бы один из параметров (операндов) относится к типу класса или типу перечисления.
Таким образом, если у вас есть указатель на объект некоторого типа класса, который перегружает оператор индекса, вы должны разыменовать этот указатель, чтобы вызвать его перегруженный оператор индекса.
В вашем примере a
имеет тип MyClass *
; это тип указателя, поэтому для указателей используется встроенный оператор []
. Когда вы разыменовываете указатель и получаете MyClass
, у вас есть объект типа класса, поэтому используется перегруженный оператор []
.
Проще говоря, с a [1]
указатель a
обрабатывается как массив, содержащий память, и вы пытаетесь получить доступ 2-й элемент в массиве (которого не существует).
(* a) [1]
заставляет сначала получить фактический объект в местоположении указателя, (* a)
, а затем вызвать для него оператор []
.
Поскольку
является указателем типа на MyClass, а не MyClass. Изменение языка для поддержки желаемого использования нарушит семантику многих других языков.
Вы можете получить желаемый синтаксический результат:
struct foo {
int a[10];
int& operator [](int i) { return a[i]; }
};
main() {
foo *a = new foo();
foo &b = *a;
b[2] = 3;
}