Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Case 0: return v0; //break не нуженСодержание книги
Поиск на нашем сайте
case 1: return v1; // case 2: return v2; // case 3: return v3; // default: return v0; } } int PArr::operator[] (unsigned i) { return GetInt(i); } Несмотря на простоту, класс PseudoArray содержит все необходимые компоненты для перегрузки оператора индексирования массива. В классе объявляются четыре закрытых целочисленных члена в строках 5-8. В строке 13 объявляется функция-член operator[] с одним беззнаковым параметром. Параметр служит индексом в массиве и может иметь произвольный тип. В строке 12 демонстрируется обычный способ доступа к закрытым данным класса с помощью функции-члена GetlntO, возвращающей одно из целочисленных значений класса. Вы можете объявить объект класса и отобразить второе значение с помощью следующих операторов: PArray ра(10, 20, 30, 40); cout «"Value #2 == " «pa.Getlnt(i); // Вызов функции-члена Это обычный способ "добраться" к закрытым членам класса. Поскольку в классе перегружен оператор индексации, вы также можете использовать следующий оператор: cout «"Value #2 == " «ра[1]; // pa используется в качестве массива В строке 21 приводится еще один пример. Выражения ра[1] и ра[2], оказывается, обеспечивают доступ к массиву несмотря на то, что указатель ра в действительности ссылается на объект класса. Перегрузка оператора индексации дает возможность использовать в массиве индексацию (удобный и ясный способ доступа к нескольким значениям) вместо вызова функции-члена для объекта класса. Имейте в виду, что индексы перегруженных массивов могут быть произвольными типами данных. Например, вы можете заменить строку 13 на: int operator[](char с); и затем использовать символьные индексы, подобные символам от 'А' до 'D', для индексации массива с начальным индексом 'А', в отличие от обычных массивов в С и C++, в которых используются целочисленные индексные значения, начинающиеся с нуля. По сути, перегружая [] и используя символы в качестве индексов, вы устанавливаете соответствие между множеством символов и множеством значений, создавая тем самым так называемый ассоциативный массив. Вы можете реализовать функцию-член перегрузки оператора [] следующим образом: int PseudoArray::operator[](char с) return Getlnt(c - 'A'); } Затем вы можете использовать символьную переменную в качестве индекса массива. Например, после внесения предыдущих изменений замените строки 20-21 на следующие: for (char с = 'A'; c<='D'; с++) cout «"ра[" «с «"] == " «ра[с] «'\n';
Оператор вызова функции Перегрузка вызова функции operator() делает объект класса похожим на функцию, которую можно вызвать. Перегруженная функция operator() может возвращать значения заданных типов или вовсе ничего не возвращать. В ней также могут объявляться параметры. Она не может быть статическим членом класса. Пример4.20 класса с перегруженным оператором вызова функции, возвращающим целочисленное значение: #include <iostream.h> #include <conio.h> class TAClass { int х; public: //Перегруженная функция-член int operator() (void); TAClass (int n) { x = n; } }; //В классе TAnyClass перегружается //оператор вызова функции с //помощью объявления int //operator()(void); //Можно заменить void списком //необходимых параметров. //Перегруженная функция-член int TAClass::operator()(void) {return x; } В этом примере функция operatorO возвращает целочисленные значения члена х объекта TAClass. main() {clrscr(); TAClass object = 100; int q = object(); // вызов функции! //выполняется оператор // object. Operator()(); cout << q; getch(); return 0; }
Второй оператор похож на вызов функции с именем objectO, но на самом деле выполняется оператор object. Operator()();.
Оператор доступа к члену класса Унарный оператор доступа к члену класса -> перегружается как operator->(). Он не м.б. статической функцией-членом класса. Можно перегрузить -> для класса TAClass следующим образом: //Пример 4.21 //4_22 #include <iostream.h> #include <conio.h> class TAClass { int x, y; public: TAClass(int xx, int yy) { x = xx; y = yy; } TAClass* operator->(); //Функция-член operator->() //возвращает объект, ссылку или //указатель на объект класса. //В данном случае возвращает //указатель на класс TAClass. int GetX(void) { return x; } int GetY(void) { return y; } }; TAClass* TAClass:: operator->() { cout << "\n Доступное данное: "; //указатель, ссылающийся на объект, //для которого была вызвана //функция-член return this; } Main() { TAClass t(100, 200); cout << t->GetX() << '\n'; cout << t->GetY() << '\n'; // На самом деле вып-ся так: //cout«(t.operator->())->GetX() //«'\n'; //cout«(t.operator->())->GetY() //«'\n'; getch(); return 0; }
Результат: Accessing member: 100 Accessing member: 200
Функция-член operator->() должна возвращать объект, ссылку или указатель на объект класса. В данном I случае она возвращает указатель на класс TAnyClass. Оператор реализуется следующим образом: I TAClass* TAClass::operator->() { cout «"\nAccessing member: "; return this; } В данном примере демонстрируется использование перегрузки оператора -> в качестве отладочного трюка [ Перегруженный оператор выводит короткое сообщение перед тем, как вернуть указатель this, ссылающийся на объект, для которого была вызвана функция-член. В основной программе перегруженный оператор может применяться для объектов класса TAClass следующим образом: main() { TAnyClass t(100, 200); cout «t->GetX() «'\n'; cout «t->GetY() «'\n' return 0; } В двух операторах вывода в поток используется перегруженный оператор -> для доступа к функциям-членам GetXO и GetY() объекта t класса TAnyClass, На самом деле, эти операторы выполняются так, как приведенные ниже: cout «(t.operator->())->GetX() «'\n'; cout «(t.operator->())->GetY() «'\n'; Поэтому программа отобразит метки перед значениями, возвращаемыми функциями GetXO и GetY(): Accessing member: 100 Accessing member: 200
Операторы инкремента и декремента В ранних версиях C++ было невозможно определить отдельные перегруженные операции для постфиксных и префиксных операторов ++ и —. Пример 4.23 class TAClass { int x; public: TAnyClass(int xx) { x = xx; } int operator++() { return x++;} int operator++(int) { return x++;} int operator--() { return ++x; } int operator--(int) { return ++x;} int GetX(void) < return x; } Функция-член operator++() определяет префиксный оператор инкремента для объекта типа TAnyClass; эта функция не имеет параметров. Функция-член operator++(int) определяет постфиксный оператор инкремента для объекта типа TAnyClass; C++ присваивает нуль единственному целочисленному параметру. Демонстрационные функции реализуются встраиваемыми, однако они могут реализоваться и отдельно. Для объекта v типа TAnyClass выражение ++v вызовет перегруженный префиксный оператор ++. В действительности выполняется оператор x.operator++();. Выражение v++ вызовет перегруженный постфиксный оператор ++ и выполнится, как x.operator++(0);. Операторы декремента работают аналогичным образом.
main() { TAnyClass t(100); cout «"t == " «t.GetXO <<t.GetX() <<”; ++t<<’\n’; cout «"t == " «t.GetX() << t.GetX() <<”; t++<<’\n’; cout «"t == " «t.GetX() << t.GetX() <<”; --t<<’\n’; cout «"t == " «t.GetX() << t.GetX() <<”; t--<<’\n’; } //4_23 #include <iostream.h> #include <conio.h> class TAClass { int x; public: TAClass(int xx) { x = xx; } int operator++() { return ++x;}; int operator++(int) { return x++;} Int operator--() { return --x; } Int operator--(int) { return x--;} int GetX(void) { return x;} }; main() { TAClass t(100); clrscr(); cout<<"t=="<<t.GetX() <<";++t==" << ++t<<"\n"; cout<<"t=="<<t.GetX()<< ";t++==" << t++<<"\n"; cout<<"t ==" << t.GetX() << ";--t==" << --t<<"\n"; cout<<"t=="<<t.GetX()<<";t--==" << t--<<"\n"; getch(); return 0; } Результат: t=101; ++t=101 T=102; t++=101 T=101; --t=101 T=100; t--=101 Другие вопросы, касающиеся перегрузки операторов Получив некоторое представление о перегрузке операторов, необходимо иметь в виду следующие факты. • C++ "не понимает" семантики перегруженного оператора. Вы должны обеспечить осмысленные функции перегрузки операторов. • C++ не может выводить сложные операторы из простых. В классе, в котором объявлены функции перегрузки операторов operator*() и operator=(), C++ не сможет вычислить выражение а *= b до тех пор, пока вы не перегрузите operator*=(). • Никогда не изменяйте синтаксис перегруженных операторов. Бинарные операторы должны оставаться бинарными, унарные — унарными. Например, нельзя создать унарное деление, поскольку такой встроенной возможности в C++ не существует. • Нельзя изобретать новые операторы. Вы можете перегружать только операторы, перечисленные в табл. 15.1. • Нельзя перегружать символы препроцессора # и ##.
|
||||
Последнее изменение этой страницы: 2016-08-01; просмотров: 244; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.149.214.223 (0.008 с.) |