![]() Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь 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; просмотров: 250; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.119.122.88 (0.01 с.) |