|
Программирование >> Аргументация конструирования
Я осознаю, что это слабый аргумент, тем не менее перегрузка операторов может быть полезной. Допустим, у нас есть класс usDoliar, который представляет вечнозеленые американские доллары. Некоторые операторы не имеют никакого смысла в применении к долларам. Например, какую смысловую нагрузку будет нести инверсия (оператор -) в применении к долларам? Перевернуть бумажку на другую сторону? Обменять на гривну? С другой стороны, некоторые операторы явно применимы к этому классу. Например, имеет смысл складывать или вычитать объекты класса USDollar - результатом будет тот же USDollar. Кроме того, имеет смысл умножать или делить USDollar на два. Или три. Но очень трудно себе представить умножение USDollar на USDollar... Перегрузка простых арифметических операторов для класса USDollar может значительно улучшить читаемость программы. Сравните два приведенных ниже фрагмента кода: expense - посчитать количество уплаченн1х денег (учитыхвая проценте! и требуемую сумму) USDollar expense (USDollar principle, double rate) подсчитаем проценты USDollar interest = principle.interest(rate); добавим это к требуемой сумме и вернем результат returnprinciple. add(interest) ,- Если перегрузить операторы, же функция примет такой вид: expense - посчитать количество уплаченн1х денег (учит1вая проценты и требуею сумму) USDollar expense(USDollar principle, double rate) USnOoUar interest = principle*rate; return ciple + interest; Ну как, красиво? Однако, прежде чем вы научитесь перегружать операторы, вы должны понять взаимосвязь между оператором и функцией. На секунду задумайтесь над тем, что такое оператор? Ведь это не более чем встроенная функция со своеобразным синтаксисом. Например, какая разница между а+Ь и +(а,Ь)? Или, например, add(a,b)? Никакой. Между прочим, в некоторых языках сложение именно так и происходит. C++ дает каждому оператору специальное функциональное имя, которое состоит из ключевого слова operator, следующего за ним символа оператора и расположенных после него соответствующих типов аргументов. Например, оператор +, который выполняет сложение двух переменных типа int и лает на втходе int, по сути, вызывается как функция: int operator+(int, int). Оператор, складывающий целочисленные значения, отличается от оператора, складывающего значения типа double (он будет выглядеть как double operator+(double, double)). Это не так трудно понять, если вспомнить, что внутренний формат переменной типа int отличается от формата переменной типа double. Вы не можете изобретать новые операторы либо изменять приоритет или формат существующих операторов. Кроме того, нельзя переопределять операторы для встроенных типов. Вы также вряд ли сможете внятно объяснить, что такое сложение двух цедочисденных значений (есди, конечно, не имеете соответствующей ученой степени). Приведенные ниже примеры демонстрируют, как могут быть определены операторы сложения и инкремента для класса USDollar (я мог бы реализовать такие же функции и для канадских долларов, но тогда мне бы понадобился канадец для придания комментариям канадского акцента). l.Lar - объект, который содержит целое число долларов плюс целое числ -тов. Сто центов равны одному доллару class USDDllar ( friend USDollar lari, USDollaru) ; friend USDollarS operator++(USDollar£) ; public: USDollar (un.3igned int d, unsigned int c) ; protected: unsigned int dollars; unsigned int cents; конструктор USDollar;:USDollar(unsigned int d, unsigned int c) dollars = d; cents = c; while (cents >= 100) t dollars++; cents -= 100; складывает с и возвращает результат в виде нового объекта USDollar operatort(USDollars si, USDollarS s2) unsicned int cents = si.cents + s2.cents; unsigned in lars llars + s2. dollars USDcJlar d(dollars, cents); return d; operator++ - увеличивает указанный аргумент, изменяя значение объекта USDollarS operator+T (USDollari s) s.cents++; ents >= 100) ;5. cents -= 100; s.dollars++; return indnt argcs, cha* pArgs [ 3) иШэПаг d3(0, 0); d3 = dl +.d2; ++d3; return 0; Класс USDollar определен как класс, содержащий целое число долларов и целое число центов. Количество центов не должно превышать 100. Конструктор вводит еще одно правило, в соответствии с которым количество центов уменьшается на сто, если оно больше этой цифры, а количество долларов соответственно увеличивается. В данном примере operator+ и operator++ бьши реализованы как обычные внешние функции, которые являются друзьями класса USDollar. Скажи мне, кто твой друг... Вы уже встречались со словом friend в главе 16, Защищенные члены класса: не 1 беспокоить! . Скажу о нем несколько слов, чтобы вам не пришлось лишний раз листать книгу. Внутри класса вы можете объявить внешнюю функцию как друга : класса. Дружественная функция имеет все права и привилегии, которые присушим ; членам класса. Объявляя. функцию operator+ () другом, я предоставляю ей доступ : к защищенным членам класса USDollar. Сравнение класса с семьей имеет тот же смысл, что и в нашей дискуссии об управлении доступом к классу. Например, все члены семьи имеют доступ к фа- \ мильному серебру (кроме сумасшедшей тетушки, однако не будем об этом). Большинству людей, . за исключением тех, кого семья выбрала своими друзьями, не по- I зволено прикасаться к фамильному серебру. В этом случае друг семьи имеет доступ к фамильному серебру. И первое, в чем семья доверяет другу, - это в том, что он не будет злоупотреблять доверием. Заметьте, что человек не может объявить себя другом семьи; только семья может ; решить, друг он или нет. То же применимо и к классам: функция пе может объя- ; вить себя другом класса. Таким образом, ключевое слово friend имеет смысл f только внутри объявления класса. Одна семья может предложить другой семье быть их друзьями. Это значит, что каждый член второй семьи имеет доступ к семейному серебру первой. Точно так же { один класс может объявить другой класс другом, и это будет означать, что каждая функция-члеп второго класса яаляется другом для первого. Это не значит, что вы- \ полняется обратное: объявление класса в как друга класса А предоставляет в дос- : туп к защищенным членам класса А, однако не предоставляет доступа функциям-членам класса А к защищенным членам класса в. ; Поскольку operator+() бинарный (т.е. требует два аргумента), вы видите в объявлении два аргумента для функции (si и s2). Функция operator+() берет sin складывает его с s2. Результат этого действия возвращается как объект U Dollar. Унарным оператором, таким как operator + + (), требуется один аргумент. В данном случае operator++ () увеличивает поле, в котором содержится сумма в центах. Если эта сумма превышает 100 толе, содержащее сумму в долларах, увеличивается на 1, а поле, содержащее центы, обнуляется,
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |