Void main()
{
const Point2D p1(1,2);
Point2D p2(2,3), p3;
(p1-p2).print();//неявный вызов операции минус
p1.operator-(p2).print();//явный вызов
cout<<p1*p2<<”\n”;
(p1-20).print();//будет использоваться операция преобразования типов
}
Надо обратить внимания, что имеется оператор с двумя переменными, выражение p1-20 будет корректно выполняться. В этом случае конструктор автоматически организует вызов конструктора с одним параметром и конструируется для него временный объект. И лишь после этого вызовет функцию-операцию. 2.0-p1 конструироваться не будет, потому что перегруженная операция является методом класса своего первого оператора, а для своего типа данных никакие перегрузки операций недопустимы.
Операции с С++ можно перегружать. Не перегружаются следующие операции:
.
.*
::
? :
sizeof
Можно перегружать + * / % ^ & |~ != <> += -= /= == && || ++ ->* -> [] () new delete
Большинство операций не может быть равно перегрузке. То есть те операции ,которые выполняются раньше при перегрузке будут вести себя раньше. Изменить количество оперантов, которые берет на себя операция, невозможно. Перегружаемые унарные операции остаются унарными, а бинарные – бинарными. Нельзя создавать новые операции, можно перегружать только существующие. Нельзя изменить с помощью перегрузки операций смысла работы с переменами встроенного типа.
Дружественные функции
Те функции, которые не находятся в классе, но имеют доступ к его закрытой части.
Point2D p1, p2(1,2), p3;
(p1+p2).print();
(p1+2.0).print();
(2.0+p2).print();//ошибка компиляции
В некотором случае хотелось бы более свободно использовать перегруженные операции дял объекта Point2D. Это в принципе возможно,… При этом из глобальных функций будет невозможен доступ к закрытой части класса, а следовательно работа с самым классом. В С++ есть возможность разрешить доступ к закрытым частям класса глобальным функциям или член-функциям другого класса. Для разрешения доступа из этих функций ко всем данным класса надо перечислить эти функции в описании класса ключевым словом friend, создав таким образом дружественные классу функции.
//point2d.cpp
Point2D operator +(Point2D p1, Point2D p2)
{
return Point2D(p1.x+p2.x, p1.y+p2.y);}
//point2d.h
friend Point2D operator+(Point2D, Point2D);//дружественная к оператору +
Спецификатор доступа private, protected, public не имеет отношения к дружественности, так что это описание может помещаться в любом месте описания класса.
Рекомендуется помещать определения дружественности первыми в классе непосредственно после его заголовка и не предварять его каким-либо спецификатором доступа
Так как функции, объявленные как friend не являются член-функциями этого класса им не передается неявный указатель на объект класса. Значит этот аргумент должен быть явно указан в списке аргументов функции.
При определении дружественной функции для доступа к полям всем аргументов, надо использовать составные имена.
ostream <<Point2D
ostreamf – возвращаемое значение
friend ostream& operator <<(ostream &, Point2D);
friend istream& operator >>(istream&, Point2D&);
