Вывод из всего сказанного может быть только один: не все операции должны быть реализованы как методы класса. Очевидно, что кандидаты в методы — это, в первую очередь, те операции, у которых левым аргументом является текущий объект. Например, это все операции с присваиванием. И напротив, если в операции левым аргументом может быть объект, тип которого отличается от реализуемого типа, такую операцию лучше не включать в методы, а реализовать как внешнюю функцию. К таким операциям, в первую очередь, относятся операции ввода-вывода, коммутативные операции сложения, вычитания, умножения и ряд других. Брюс Эккель в [11] приводит рекомендации Роба Мюррея по выбору формы перегрузки (табл. 3.2).
Таблица 3.2. Форма перегрузки операций
Операция Рекомендуемая форма перегрузки
Все унарные операции Метод класса
- [] () -> ->* Обязательно метод класса
+ *= /= %= &= |= л= «= »- Метод класса
Остальные бинарные операции Внешняя функция
Однако, как мы знаем, внешние функции не имеют доступа к приватной части класса. Страуструп Б., очевидно, тоже столкнулся с такими проблемами, поэтому он их решил, включив в язык механизм «друзей» (см. п. 11.4 в [1]). «Друзья» класса — это внешние функции, другие классы или методы других классов, которые имеют доступ к закрытым частям нашего класса. Программистам необходимо поддерживать себя в форме - беговая дорожка отзывы тут.
Для того чтобы внешняя функция стала другом класса, необходимо в интерфейсе класса объявить ее прототип, добавив спереди слово friend. Например, дружественная функция умножения денежной суммы на число может быть описана в интерфейсе класса следующим образом:
friend TMoney operator*(const long double &a, const TMoney &b);
Реализация же функции не должна содержать в заголовке ни слова friend, ни префикса класса TMoney: :, например:
TMoney operator*(const long double &a, const TMoney &b) { TMoney t = b;
t*=a;
return t;
}
И опять обратите внимание на то, что мы при реализации новой операции использовали уже проверенный метод класса — операцию с присваиванием *=.
СОВЕТ
Реализуйте в качестве методов класса только те операции, которые имеют своим левым аргументом объект класса. Реализуйте как дружественные функции те бинарные операции, которые могут иметь левым аргументом не объект класса. |