7.2.2 Предопределенные свойства операций Используется только несколько предположений о свойствах пользовательских операций. В частности,
operator=, operator[], operator() и operator-> должны быть нестатическими функциями-членами. Этим
обеспечивается то, что первый операнд этих операций является адресом.
Для некоторых встроенных операций их интерпретация определяется как комбинация других операций,
выполняемых над теми же операндами. Так, если a типа int, то ++a означает a+=1, что в свою очередь
означает a=a+1. Такие соотношения не сохраняются для пользовательских операций, если только
пользователь специально не определил их с такой целью. Так, определение operator+=() для типа
complex нельзя вывести из определений complex::operator+() и complex operator=().
По исторической случайности оказалось, что операции = (присваивание), &(взятие адреса) и , (операция
запятая) обладают предопределенными свойствами для объектов классов. Но можно закрыть от
произвольного пользователя эти свойства, если описать эти операции как частные:
class X {
//
...
private:
void
operator=(const
X&);
void
operator&();
void
operator,(const
X&);
//
...
};
void f(X a, X b)
{
a=
b;
// ошибка: операция = частная
&a;
// ошибка: операция & частная
a,b
// ошибка: операция , частная
}
С другой стороны, можно наоборот придать с помощью соответствующих определений этим операциям
иное значение.
7.2.3 Операторные функции и пользовательские типы Операторная функция должна быть либо членом, либо иметь по крайней мере один параметр,
являющийся объектом класса (для функций, переопределяющих операции new и delete, это не
обязательно). Это правило гарантирует, что пользователь не сумеет изменить интерпретацию
выражений, не содержащих объектов пользовательского типа. В частности, нельзя определить
операторную функцию, работающую только с указателями. Этим гарантируется, что в С++ возможны
расширения, но не мутации (не считая операций =, &, и , для объектов класса).
Операторная функция, имеющая первым параметр основного типа, не может быть функцией-членом.
Так, если мы прибавляем комплексную переменную aa к целому 2, то при подходящем описании
функции-члена aa+2 можно интерпретировать как aa.operator+(2), но 2+aa так интерпретировать нельзя,
поскольку не существует класса int, для которого + определяется как 2.operator+(aa). Даже если бы это
было возможно, для интерпретации aa+2 и 2+aa пришлось иметь дело с двумя разными функциями-
членами. Этот пример тривиально записывается с помощью функций, не являющихся членами.
Каждое выражение проверяется для выявления неоднозначностей. Если пользовательские операции
задают возможную интерпретацию выражения, оно проверяется в соответствии с правилами $$R.13.2.