Читаем C++ онлайн бесплатно
void f(complex a, complex b) (* complex c = a + b; // сокращенная запись complex d = operator+(a,b); // явный вызов *)
При наличии предыдущего описания complex оба инициализтора являются синонимами.
Бинарная операция может быть определена или как функция член, получающая один параметр, или как функция друг, получющая два параметра. Таким образом, для любой бинарной оперции @ aa@bb может интерпретироваться или как aa.operator@(bb), или как operator@(aa,bb). Если определены обе, то aa@bb является ошибкой. Унарная операция, префиксная или постфиксная, может быть определена или как функция член, не получающая параметров, или как функция друг, получающая один параметр. Таким образом, для любой унарной операции @ aa @ или @aa может интерпретироваться или как aa.operator@(), или как operator@(aa). Если определено и то, и другое, то и aa@, и @aa являются ошибками. Рассмотрим следующие примеры:
class X (* // друзья
friend X operator-(X); // унарный минус friend X operator-(X,X); // бинарный минус friend X operator-(); // ошибка: нет операндов
friend X operator-(X,X,X); // ошибка: тернарная
// члены (с неявным первым параметром: this)
X* operator amp;(); // унарное amp; (взятие адреса) X operator amp;(X); // бинарное amp; (операция И) X operator amp;(X,X); // ошибка: тернарное
*);
Когда операции ++ и – перегружены, префиксное использвание и постфиксное различить невозможно.
Относительно смысла операций, определяемых пользоватлем, не делается никаких предположений. В частности, посколку не предполагается, что перегруженное = реализует присваивание ее первому операнду, не делается никакой провеки, чтобы удостовериться, является ли этот операнд lvalue (#с.6).
Значения некоторых встроенных операций определены как равносильные определенным комбинациям других операций над тми же аргументами. Например, если a является int, то ++a оначает a+=1, что в свою очередь означает a=a+1. Такие соотншения для определяемых пользователем операций не выполняются, если только не случилось так, что пользователь сам определил их таким образом. Например, определение operator+= () для тпа complex не может быть выведено из определений complex::operator+() и complex::operator=().
По историческому совпадению операции = и amp; имеют опредленный смысл для объектов классов. Никакого элегантного спсоба «не определить» эти две операции не существует. Их моно, однако, сделать недееспособными для класса X. Можно, например, описать X::operator amp;(), не задав ее определения. Если где-либо будет браться адрес объекта класса X, то компновщик обнаружит отсутствие определения*. Или, другой способ, можно определить X::operator amp;() так, чтобы она вызывала ошику во время выполнения.
____________________ * В некоторых системах компоновщик настолько «умен», что ругается, даже если неопределена неиспользуемая функция. В таких системах этим методом воспользоваться нельзя. (прим атора)
Функция операция должна или быть членом, или получать в качестве параметра по меньшей мере один объект класса (фунциям, которые переопределяют операции new и delete, это длать необязательно). Это правило гарантирует, что пользовтель не может изменить смысл никакого выражения, не включающего в себя определенного пользователем типа. В часности, невозможно определить функцию, которая действует ислючительно на указатели.
Функция операция, первым параметром которой предполагется основной встроенный тип, не может быть функцией членом. Рассмотрим, например, сложение комплексной переменной aa с целым 2: aa+2, при подходящим образом описанной функции члне, может быть проинтерпретировано как aa.operator+(2), но с 2+aa это не может быть сделано, потому что нет такого класса int, для которого можно было бы определить + так, чтобы это означало 2.operator+(aa). Даже если бы такой тип был, то для
того, чтобы обработать и 2+aa и aa+2, понадобилось бы две различных функции члена. Так как компилятор не знает смысла +, определяемого пользователем, то не может предполагать, что он коммутативен, и интерпретировать 2+aa как aa+2. С этим примером могут легко справиться функции друзья.
Все функции операции по определению перегружены. Функция операция задает новый смысл операции в дополнение к встроеному определению, и может существовать несколько функций опраций с одним и тем же именем, если в типах их параметров имеются отличия, различимые для компилятора, чтобы он мог различать их при обращении (см. #4.6.7).
Приведенная во введении реализация комплексных чисел слишком ограничена, чтобы она могла устроить кого-либо, потому ее нужно расширить. Это будет в основном повторением описанных выше методов. Например:



