Идиомы и стили С++ | страница 18
> // если выскочило исключение, сюда мы не попадем.
> } catch (…) {
> // да еще и исключения обработать.
> }
>};
Все…
Шаг 13 - Перегрузка operator+.
Оператор operator-› мы уже перегружали. Результаты получились просто феерические. Давайте замучаем еще кого-нибудь и посмотрим, что получится? Давайте. Первейшим кандидатом на переопределение является оператор operator+,потому что в жизни (помимо С++) он выражает замечательное действие - добавление объекта к другому объекту. Конечно, Вы можете придать ему и другой смысл, но это будет как раз тот случай, где "если хочешь быть здоров - ешь один, и в темноте"…
Проиллюстрирую сказанное следующим примером: Вы пишете интерфейс на Паскале, и для добавления подменю или пункта меню используете функции AddSubMenu() и AddMenuItem(). Тогда для создания меню Вы прописываете замечательно изящное выражение с толстым-толстым слоем скобок в конце:
>Menu.AddSubMenu(Submenu1,
> AddMenuItem(MenuItem1,
> AddMenuItem(MenuItem2,
> AddMenuItem(MenuItem3,
> AddSubMenu (SubMenu2, nil)
>))));
А вот что получается на С++:
>CMenu Menu = Menu() + SubMenu1() + MenuItem1() + MenuItem2() + MenuItem3() + SubMenu2();
Прошу извинить за отсутствие подробностей - на память не помню; но и так очевидно, что выражение в C++ выглядит просто красивее. Это одно из главных достоинств С++ - язык позволяет выражать наши намерения предельно ясно.
Есть еще один смысл, который можно придать оператору operator+, если "от перестановки мест слагаемых сумма не изменяется". Примером, кроме сложения и умножения чисел, может быть соударение объектов: столкнулся ли Титаник с айсбергом, айсберг ли столкнулся с Титаником, результат один - вызов деструктора для Титаника. (Я не утверждаю, что это НУЖНО делать так, это только можно!)
Немного ниже мы используем это для уменьшения количества диспетчерских функций при двойной диспетчеризации из Шага 4, а сейчас быстренько напишем код с переопределением operator+ для любимого стека всех времен и народов. Понятно, на месте стека может оказаться каждый, те же меню, опять же.
>class CArray {
>private:
> int a[100];
> int iTop;
>public:
> CArray ():iTop(0) {}
> CArray (const CArray& _ca) {
> iTop = _ca.iTop;
> for (int i=0; i++; i ‹100) a[i]= _ca.a[i];
> }
> CArray& operator=(const CArray& _ca) {
> if (this==&_ca) return *this;
> for (int i=0; i++; i ‹100) a[i]= _ca.a[i];
> iTop = _ca.iTop;
> return *this;
> };
> // С этим еще можно согласиться
> CArray& operator+ (int _i) { a[iTop]=_i; iTop++; return *this; }