При обсуждении сходства и различий между Java и C ++ возникает большое заблуждение, которое возникает в вашем вопросе.Ссылки на C ++ и ссылки на Java не совпадают.В Java ссылка - это сбрасываемый прокси для реального объекта, а в C ++ ссылка - это псевдоним для объекта.Чтобы выразить это в терминах C ++, ссылки на Java - это указатель для сборки мусора, а не ссылка.Теперь, возвращаясь к вашему примеру, чтобы написать эквивалентный код на C ++ и Java, вы должны будете использовать указатели:
int main() {
type a(1), b(2);
type *pa = &a, *pb = &b;
pa = pb;
// a is still 1, b is still 2, pa == pb == &b
}
Теперь примеры такие же: оператор присваивания применяется к указатели на объекты, и в этом конкретном случае вы также не можете перегрузить оператор в C ++.Важно отметить, что перегрузкой оператора можно легко злоупотреблять, и это является хорошей причиной, чтобы избежать ее в первую очередь.Теперь, если вы добавите два разных типа сущностей: объекты и ссылки, вещи станут более беспорядочными.
Если бы вам было позволено перегрузить operator=
для определенного объекта в Java, вы бы не сталиможет иметь несколько ссылок на один и тот же объект, и язык будет поврежден:
Type a = new Type(1);
Type b = new Type(2);
a = b; // dispatched to Type.operator=( Type )??
a.foo();
a = new Type(3); // do you want to copy Type(3) into a, or work with a new object?
Это, в свою очередь, сделает тип непригодным для использования в языке: контейнеры хранят ссылки, и они переназначают их (даже первыевремя, когда объект создается), функции на самом деле не используют семантику передача по ссылке , а скорее передачу по значению ссылки (что является совершенно другой проблемой)опять же, разница составляет void foo( type* )
против void foo( type& )
: прокси-объект копируется, вы не можете изменить ссылку , переданную вызывающей стороной.
Проблема в том, что языкочень стараюсь скрыть тот факт, что a
и объект, на который a
ссылается , не одно и то же (то же самое происходит в C #), и что яn очередь означает, что вы не можете явно указать, что к ссылке / референту должна применяться одна операция, которая разрешается языком.Результатом этого проекта является то, что любая операция, которая может быть применена к ссылкам, никогда не может быть применена к самим объектам.
Что касается остальных операторов, решение, скорее всего, произвольно Поскольку язык скрывает разницу между ссылками и объектами, его можно было бы спроектировать так, чтобы компилятор преобразовал a+b
в type* operator+( type*, type* )
.Поскольку вы не можете использовать арифметику, проблем не будет, так как компилятор распознает, что a+b
- это операция, которая должна применяться к объектам (это не имеет смысла со ссылками).Но тогда может показаться немного неловким, что вы можете перегрузить +
, но вы не можете перегрузить =
, ==
, !=
...
Это путь, по которому C # пошел, гденазначение не может быть перегружено для ссылочных типов.Интересно, что в C # есть типы значений, и набор операторов, которые могут быть перегружены для ссылочных типов и типов значений, различается.Не кодируя C # в больших проектах, я не могу точно сказать, является ли этот потенциальный источник путаницы таковым или люди просто привыкли к нему (но если вы будете искать SO, вы обнаружите, что несколько человек спрашивают , почему X не можетбыть перегруженным в C # для типов ссылок , где X является одной из операций, которые могут быть применены к самой ссылке.