КАТЕГОРИИ: Архитектура-(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 string
{ char *Str; int size; public: string &operator= (string&); }; string& string::operator= (string& right) { if (Str!=NULL) delete Str; // Освободить динамическую память size = right.size; // Резервировать память Str = new char[size + 1]; strcpy(Str,right.Str); // Копировать строки return *this; } Перегруженные операции индексирования, вызова функций, инкремента и декремента префиксных и постфиксных. Переопределение операции () позволяет использовать синтаксис вызова функции применительно к объекту класса (имя объекта с круглыми скобками). Количество операндов в скобках может быть любым. Переопределение операции [] позволяет использовать синтаксис элемента массива (имя объекта с квадратными скобками). //------Переопределение операций [] и () #include <string.h> class string // Строка переменной длины { char *Str; // Динамический массив символов int size; // Длина строки public: // Операция выделения подстроки string operator()(int,int); // Операция выделения символа char operator[](int); int operator[](char*); // Операция поиска подстроки }; //------ Операция выделения подстроки ------------------- string string::operator()(int n1, int n2) { string tmp = *this; delete tmp.Str; tmp.Str = new char[n2-n1+1]; strncpy(tmp.Str, Str+n1, n2-n1); return tmp; }; Пример переопределения операции инкремента приведен выше. Переопределение декремента производится аналогично. Заметим только, что когда операции ++ и -- перегружены, префиксное использование и постфиксное в классическом С++ различить невозможно. В современной версии языка (Microsoft Visual C++ 6.0) принято соглашение, что перегрузка префиксных операций ++ и -- ничем не отличаются от перегрузки других унарных операций, то есть дружественные функции operator++() и operator--() с одним параметром некоторого класса определяют префиксные операции ++ и --. Операции - члены класса без параметров определяют те же префиксные операции. При расширении действия постфиксных операций ++ и –– операции-функции должны иметь еще один дополнительный параметр типа int. Если для перегрузки используется операция - член класса, то она должна иметь один параметр типа int. Если операция определена как дружественная функция, то ее первый параметр должен иметь тип класса, а второй - тип int. Когда в программе используется соответствующее постфиксное выражение, то операция - функция вызывается с нулевым целым параметром.
Рассмотрим пример применения разных операций - функций для постфиксной и префиксной операций ++ и --. class pair // класс «пара чисел» { int N; // целое double x; // вещественное friend pair& operator++(pair&); //дружественная для префикса friend pair& operator++(pair&,int);//дружественная для постфикса public: pair (int n, double xn) //конструктор { N = n; x = xn; }; void display () //вывод значения { printf (”N = % d x = % f ”, N, x); }; pair& operator–– () //член для префикса { N /= 10; x /= 10; return *this; }; pair& operator–– (int k) //член для постфикса { N /= 2; x /= 2; return *this; }; }; pair& operator++ (pair & P) // дружественная для префикса { P.N *= 10; P.x *= 10; return P; }; pair& operator++ (pair & P, int k) // дружественная для постфикса { P.N = P.N * 2 + k; P.x = P.x * 2 + k; return P; }; void main() { pair Z (10, 20.0); //вызов конструктора Z.display(); //N = 10 x = 20 ++Z; Z.display(); //N = 100 x = 200 --Z; Z.display(); //N = 10 x = 20 Z++; Z.display(); //N = 20 x = 40 Z--; Z.display(); //N = 10 x = 20 }; Для демонстрации полной независимости смысла перегруженной операции от ее традиционного значения в операциях - функциях для префиксных операций ++ соответствует увеличению в 10 раз, а –– уменьшению в 10 раз. Для постфиксных операций ++ определена как увеличение в 2 раза, а - -- уменьшение в 2 раза. Попытки использовать в постфиксных операциях значение дополнительного параметра int k подтверждают его равенство 0. Перегрузка new, delete. Операции создания и уничтожения объектов в динамической памяти могут быть переопределены следующим образом void* operator new(size_t size);
void operator delete (void *); где void* - указатель на область памяти, выделяемую под объект, size - размер объекта в байтах, size_t - тип размерности области памяти, int или long. Переопределение этих операций позволяет написать собственное распределение памяти для объектов класса. Операции, не допускающие перегрузки. В С++ существует несколько операций, не допускающих перегрузки: . прямой выбор члена объекта класса; .* обращение к члену через указатель на него; ?: условная операция; :: операция указания области видимости; sizeof операция вычисления размера в байтах; # препроцессорная операция. Преобразование типов, определяемых пользователем с помощью конструкторов и операций преобразования. При работе со стандартными типами данных в Си имеют место явные и неявные преобразования их типов. По аналогии для классов также могут быть определены такие операции - они ассоциируются с конструированием объектов класса. Так, если в программе встречается преобразование типа (класса) "yyy" к типу (классу) "xxx", то для его осуществления в классе "xxx" необходим конструктор вида xxx(yyy &); Сами преобразования типов происходят в тех же самых случаях, что и обычные преобразования базовых типов данных: · при использовании операции явного преобразования типов; · при выполнении операции присваивания, если она не переопределена в виде "xxx=yyy" (транслятором создается временный объект класса "xxx", для которого вызывается указанный конструктор и который затем используется в правой части операции присваивания); · при неявном преобразовании типа формального параметра функции при передаче его по значению (вместо конструктора копирования); · при неявном преобразовании типа результата функции при передаче его по значению (вместо конструктора копирования); · при определении объекта класса "xxx" одновременно с его инициализацией объектом класса "yyy" (вместо конструктора копирования) yyy b; xxx a = b; При конструировании объекта класса "xxx" с использованием объекта класса "yyy" естественно должна быть обеспечена доступность необходимых данных последнего (например, через дружественность). В качестве примера рассмотрим обратное преобразование базового типа long к типу dat - количество дней от начала летоисчисления преобразуется к дате. Здесь же рассмотрим другой класс - man, в котором одним из элементов личной части является дата. Значение этого объекта копируется при преобразовании типа man в тип dat.
static int days[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; class man;
Дата добавления: 2014-01-13; Просмотров: 377; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |