|
Программирование >> Аргументация конструирования
Заметьте, что эта функция возвращает не объект тип ream, который она получила, а объект cout, который имеет тот же тип ostream. Тут очень легко ошибиться, поскольку cout является наиболее часто используемым объектом типа cHtrean. Эта ошибка не проявится, пока не будет использована приведенная ниже конструкция. voi ount (int account, USDollar balance, char* pName) ofstream outFile( ACCOUNTS , io3::ate); outFile < ount << balance << pName; Целочисленная переменная account выводится в outFile с помощью функции oDcrator (ostreams, int&), которая возвращает outFile. Затем в outFile с помощью функции operator (ostreams, USDollarS) аЮДЖЯ USDollar. Эта функция возвращает неправильный объект - cout вместо outFile. В результате pName ВЫВОДИТСЯ В cout вместо вывода в файл, как требуется. Создание них - ом/м/Ял/мв Наверняка вам захочется, чтобы операторы вставки в поток были настолько умны, что вы могли бы сказать им: cout baseclassobject, а уж затем С + + сам бы выбирал оператор вставки в поток необходимого подкласса, так же как он выбирает необходимую виртуальную функцию. Увы, поскольку оператор вставки в поток не является функцией-членом, вы не можете объявить его виртуальным. Однако для умного программиста это не проблема, что и демонстрирует приведенный ниже пример. ttinclude <iostreara.h> ttinclude <ioraanip.h> class Currency i public: Currency(double v = 0.0) Выделяем целую часть unit = (int)v; Округляем дробную часть cents = int((v - unit)* 100.0 + 0.5); virtual void display(ostreams out) - 0; protected: unsigned int unit; unsigned int cents; class USDollar lic Currency { public: USDollar(double v = 0.0) : Currency(v) формат отображения: S123.45 virtual void display{ostreams out) { cut << $ unit << . setfill(O) setw(2) cents << setfill ( ) ; class UAH : public Currency ( public: UAH(couble v = 0.0) : Currency(v) } формат отображения: 123.00 грн. virtual void display(ostreams out) out. unit . Установим заполнение 0 для копеек << setfill(O) << setw(2) << cents Вернем заполнение пробелами <.< setfill С ) грн. ; ostreams operator (ostreams o, CurrencyS с) с.display(о) ; return o; void fn (Currencys c) ниже вывод operator (ostreams, Currencys) работает с виртуальной функцией-членом cout Сумма равна с J \п ; in:int argcs, a*pArgs[j) создать USDollar и вывести его, используя соответствующий доллару формат IfilEijii?]; usd (1.50) ; теперь создать гривну и вывести ее ШН d(3.00) ; fn(d ; return 0; Класс Currency имеет два подкласса - USDollar и UAH В классе Currency функция display (> объяа1ена чисто виртуальной. В обоих подклассах эта функция перегружается с тем, чтобы выводить объект в корректном виде. Вызов display () функции operator<<() является виртуальным, и, когда функции operator<<() пе- редается объект эта функция выводит объект как доллар. Если же был пе- редан объект класса uah, opejrat.or<< () выводит его как гривну. хотя функция operator<<() и не виртуальна, то, что она вызывает виртуальную функцию, приводит к корректным результатам: Сумма разна равна Это еще одна из причин, по которой я предпочитаю перекладывать работу, связанную с выводом на функцию-член, заставляя оператор (который не является функцией-членом) обращаться к display ().
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |