КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Class dat
{ int day; int month; int year; public: void next(); // Элемент-функция вычисления следующего дня dat operator++(); // Операция ++ dat operator+(int); // Операция "дата + целое" с передачей // первого операнда через this friend dat operator+(int,dat); // Операция с явной передачей // всех аргументов по значению dat(int=0,int=0,int=0); dat(char *); ~dat(); }; //------ Функция вычисления следующего дня ----------------- // Используется ссылка на текущий объект this, // который изменяется в процессе операции void dat::next() { day++; if (day > days[month]) { if ((month == 2) && (day == 29) && (year%4 == 0)) return; day=1; month++; if (month == 13) { month=1; year++; }; }; }; //------ Операция инкремента даты ------------------------- // 1. Первый операнд по указателю this // 2. Возвращает копию входного объекта (операнда) // до увеличения // 3. Соответствует операции dat++ (увеличение после // использования) // 4. Замечание: для унарных операций типа -- или ++ // использование их до или после операнда не имеет // значения (вызывается одна и та же функция). dat dat::operator++() { // Создается временный объект dat x = *this; // В него копируется текущий объект next(); // Увеличивается значение текущего объекта return(x); // Возвращается временный объект по }; // значению //------ Операция "дата + целое" -------------------------- // 1. Первый операнд по указателю this // 2. Входной объект не меняется, результат возвращается // в виде значения автоматического объекта x dat dat::operator+(int n) { dat x; x = *this; // Копирование текущего объекта в x while (n--!=0) x.next(); // Вызов функции next для объекта x return(x); // Возврат объекта x по значению }; //------ Операция "целое + дата" ------------------------- // 1. Дружественная функция с полным списком операндов // 2. Второй операнд класса dat - передается по значению, // поэтому может модифицироваться без изменения исходного // объекта dat operator+(int n, dat p) { while (n--!=0) p.next(); // Вызов функции next для p return(p); // Возврат копии объекта p }; void main() { int i; dat a, b(17,12,1990), c(12,7), d(3), e; dat *p = new dat[10]; e = a++; d = b+15; for (i=0; i<10; i++) p[i] = p[i] + i; delete [10] p; }; Для многих переопределяемых операций тип результата совпадает с типом одного из операндов. Это позволяет выполнить подряд несколько операций в одном выражении. Возможны различные варианты реализации в соответствии со способами передачи параметров и результата: по значению или по ссылке. Отметим наиболее важные из них: //------ Операция "дата + целое" -------------------------- // 1. Функция с неявным первым операндом по указателю this // 2. Меняется значение текущего объекта // 3. Результат - ссылка на текущий объект dat& dat::operator+ (int n) { while (n--!=0) next(); // Вызов next с текущим объектом return(*this); // Возврат ссылки на объект this }; //------ Операция "дата + целое" ------------------------- // 1. Дружественная функция с полным списком аргументов // 2. Первый операнд класса dat - ссылка, меняется при // выполнении операции // 3. Результат - ссылка на операнд dat& operator+ (dat& p,int n) { while (n--!=0) p.next(); // Вызов next для объекта p, // заданного ссылкой return(p); // Возврат ссылки на p }; //----- Операция "целое + дата" -------------------------- // 1. Дружественная функция с полным списком аргументов // 2. Второй операнд класса dat - ссылка, меняется при // выполнении операции // 3. Результат - ссылка на операнд //-------------------------------------------------------- dat& operator+ (int n, dat& p) { while (n--!=0) p.next(); // Вызов next для объекта p, // заданного ссылкой return(p); // Возврат ссылки на p }; void main() { dat a,b; // "Арифметические" эквиваленты a + 2 + 3; // a = a + 2; a = a + 3; 5 + b + 4; // b = 5 + b; b = b + 4; }; Во всех трех случаях ссылка на операнд - объект класса возвращается в качестве результата. Все действия, выполняемые операцией, реализуются в том же объекте, который "накапливает" результат. Естественный "арифметический" вид переопределяемых операций получается, когда результат возвращается по значению не в виде ссылки, а в виде объекта: //------ Операция "дата + целое" -------------------------- // 1. Функция с неявным первым операндом по указателю this // 2. Изменяется автоматический объект - копия операнда // 3. Результат - значение автоматического объекта dat dat::operator+ (int n) { dat tmp = *this; // Объект - копия операнда while (n--!=0) tmp.next(); // Вызов next с объектом tmp return(tmp); // Возврат значения объекта tmp }; //------ Операция "дата + целое" ------------------------- // 1. Дружественная функция с полным списком аргументов // 2. Первый параметр класса dat передается по значению, // является копией первого операнда и меняется при // выполнении операции // 3. Результат - значение формального параметра dat operator+ (dat p,int n) { while (n--!=0) p.next(); // Вызов next для объекта p, // копии операнда return(p); // Возврат значения }; // формального параметра Во втором случае, когда формальный параметр - операнд передается по значению, он является отдельным объектом, в который копируется объект - фактический параметр. Поэтому его изменение не затрагивает входного операнда. Кроме того, в обоих случаях при возвращении объекта в качестве результата транслятор создает в вызывающей функции временный объект, в который копируется содержимое объекта-результата в операторе return. Дополнительная проблема для таких объектов заключается в их корректном конструировании. При отсутствии переопределения операции присваивания производится побайтное копирование объектов. Такая интерпретация операции присваивания некорректна, если объект имеет указатели на динамические переменные или массивы, идентификаторы связанных ресурсов и т.д.. При копировании таких объектов необходимо сначала уничтожить связанные динамические переменные и ресурсы левого операнда, а затем заново резервировать, но уже с параметрами, необходимыми для интерпретации операции присваивания:
Дата добавления: 2014-01-13; Просмотров: 352; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |