68950

Перевантаження операторів [], ()

Лекция

Информатика, кибернетика и программирование

Ці оператори також можна перенавантажувати, що породжує масу цікавих можливостей. На перевантаження цих операторів розповсюджується одне загальне обмеження: вони повинні бути нестатичними функціями-членами. Дружні функції застосовувати не можна.

Украинкский

2014-09-27

49.5 KB

0 чел.

Лекція № 12

Тема: Перевантаження операторів [], ()

План

1. Перевантаження оператора "[]"

2. Перевантаження оператор "()"

Перевантаження деяких спеціальних операторів

У мові C++ існують оператори індексування елементів масиву "[]", виклику функції "()" і доступу до члена класу "->". Ці оператори також можна перенавантажувати, що породжує масу цікавих можливостей.

На перевантаження цих операторів розповсюджується одне загальне обмеження: вони повинні бути нестатичними функціями-членами. Дружні функції застосовувати не можна.

Перевантаження оператора"[]"

При перевантаженні оператор "[]" вважається бінарним. Отже, він повинен мати такий вигляд:

тип имя_класу: : operator [] (int i) {

// ...

}

З технічної точки зору параметр не зобов'язаний мати типу int, проте функція operator [] () зазвичай застосовується для індексування елементів масиву, тому найчастіше використовують саме цілочисельний параметр.

Допустимо, що об'єкт називається о. Тоді вираз

o[3]

 перетвориться в наступний виклик функції operator [] ():

o.operator[](3)

Інакше кажучи, значення виразу, з квадратними дужками, передається функції operator[] () як явний параметр. Покажчик this посилається на об'єкт о, який генерує виклик функції.

У наступній програмі клас atype містить масив, що складається з трьох елементів. Його конструктор ініціалізував кожен елемент масиву окремим значенням. Перевантажена операторна функція operator () [] повертає значення елементу масиву по заданому індексу.

#include <iostream>

using namespace std;

class atype {

int а[3];

public:

atype(int i, int j, int до) { а[0] = i; а[l] = j; а[2] = k; }

int operator[](int i) { return а[i]; } };

int main() {

atype ob(l, 2, 3);

cout « ob[l]; // Виводить на екран число 2

return 0;

}

Функцію operator () [] можна визначити так, щоб оператор "[]" був допустимим і в лівій, і в правій частині оператора привласнення. Для цього потрібно, щоб функція operator [] () повертала посилання. Продемонструємо це за допомогою наступної програми.

#include <iostream>

using namespace std;

class atype {

int а[3];

public:

atype(int i, int j, int до) { а[0]= i; atl] = j; а[2]= k; }

int &operator[](int i) { return а[i]; } };

int main() {

atype ob(l, 2, 3);

cout « ob[l]; // Виводить на екран число 2 cout « " ";

ob[l]= 25; // Оператор [] стоїть зліва

cout « ob[l]; // Тепер на екран виводиться число 25

return 0;

}

Оскільки тепер операторна функція operator [] () повертає посилання на елемент масиву з індексом i, її можна використовувати в лівій частині оператора привласнення для модифікації елементів масиву. (Зрозуміло, оператор " [] " як і раніше можна використовувати в правій частині оператора привласнення.)

Перевантаження оператора "[]" дозволяє забезпечити контроль за виходом індексу масиву за межі допустимого діапазону, який за умовчанням не передбачений в мові C++. Створивши клас, що містить масив, і передбачивши Перевантаженого оператора "[]", можна перехопити виникаючу виняткову ситуацію. Розглянемо приклад, в якому програма передбачає перевірку діапазону індексів масиву.

// Приклад безпечного масиву.

#include <iostream>

#include <cstdlib>

using namespace std;

class atype {

int а[3];

public:

atype(int i, int j, int до) { а[0]= i; а[l]= j; а[2]= до; }

int &operator[](int i); };

// Перевірка діапазону зміни індексу для класу atype.

int &atype::operator[](int i)

{

if(i<0 || i> 2)

{

cout « "Вихід за межі допустимого диапазона\ п"; exit(l);

}

return а[i];

}

int main() {

atype ob(l, 2, 3);

cout « ob[l]; // Виводить на екран число 2 cout << " ";

ob[l]=25; // Оператор [] зліва

cout « ob[l]; // Виводить на екран число 25

ob[3] = 44; // Генерується помилка, значення 3

// лежить поза допустимим діапазоном

return 0;

}

При виконанні оператора

Оb[3] = 44;

функція operator[]() перехоплює виниклу виняткову ситуацію і припиняє виконання програми. (На практиці виконання програми зазвичай не припиняється, а замість цього викликається обробник виняткової ситуації, пов'язаної з виходом індексу за межі допустимого діапазону.)

Перевантаження оператора"()"

При перевантаженні оператора "()" створюється операторна функція, якою можна передавати довільну кількість параметрів. При цьому новий спосіб виклику функції насправді не створюється. Розглянемо приклад. Допустимо, що оператор виклику функції Перевантажений в деякому класі таким чином:

double operator()(int а, float f, char *s) ;

Крім того, припустимо, що змінна o є об'єктом цього класу. Тоді оператор

О(10, 23.34, "Привіт");

перетвориться в наступний виклик операторної функції operator ():

О.operator()(10, 23.34, "Привіт");

Як правило, при перевантаженні оператора "()" визначаються параметри, передавані функції. При виклику функції ці параметри копіюються і привласнюються відповідним аргументам. Як завжди, покажчик this посилається на об'єкт, що генерує виклик операторної функції (у даному прикладі на об'єкт про).

Розглянемо приклад Перевантаженого оператора "()" в класі loс. Він привласнює значення два своїх аргументів членам об'єкту класу 1ос, в яких зберігається значення широти і довготи.

#include <iostream>

using namespace std;

class loc {

int longitude, latitude;

public: loc() {

loc(int lg, int It) { longitude = lg; latitude = It; }

void show() {

cout << longitude « " " ;

cout « latitude « "\n"; }

loc operator+(loc op2);

loc operator()(int i, int j);

};

// Перевантажений оператор ( ) для класу loc.

loc loc::operator()(int i, int j)

{

longitude = i;

latitude = j;

return *this;

}

// Перевантажений оператор + для класу loc.

loc loc::operator+(loc op2)

{

lос temp;

temp.longitude = op2.longitude + longitude;

temp.latitude = op2.latitude + latitude;

return temp;

}

int main() {

loc ob1(10, 20), ob2(l, 1);

ob1.show();

ob1(7, 8); // Оператор застосовується самостійно

ob1.show();

ob1 = ob2 + ob1(10, 10);

// Оператора можна використовувати усередині виразів

ob1.show();

return 0;

}

Пам'ятайте, що, перенавантажуючи оператора "()", ви можете використовувати будь-який тип параметрів і будь-який тип повертаного значення. Ці типи можна вибирати залежно від конкретного застосування. Крім того, можна передбачати значення аргументів за умовчанням.


 

А также другие работы, которые могут Вас заинтересовать

36155. Русский музей 34.32 KB
  Это Строгановский и Мраморный дворцы Михайловский Инженерный замок и главное здание музея величественный Михайловский дворец с корпусом Бенуа входящий в ансамбль одной из красивейших площадей Северной столицы площади Искусств. Покровитель всего русского Александр III вынашивал план создания в Михайловском дворце музея русского искусства и такой музей здесь был открыт. История создания Русского музея Основных источников поступлений в формирующуюся коллекцию музея было не так уж много. Да и Особая комиссия проводившая по поручению...
36156. Автоматизированные системы безналичных расчетов 499 KB
  Техническое обеспечение расчетных узлов предприятий торговли и сервиса в условиях функционирования АСБР и системы штриховой идентификации товаров и услуг На предприятиях торговли и сервиса используются: устройства крепления самоклеющихся этикеток для ручного крепления этикеток со штриховыми кодами ярлыков и этикеток для автоматического крепления со штриховыми кодами на различные товары машиночитаемых ярлыков для крепления с помощью механизированных зажимов; весовые терминалы для взвешивания снабжения самоклеющимися этикетками...
36157. Физические основы магнитооптической записи 72.5 KB
  В общем случае магнитооптический эффект это изменение оптических свойств вещества в зависимости от его намагниченности или от силы приложенного к нему магнитного поля. силовые линии магнитного поля образуемого ими перпендикулярны поверхности пленки. Если на вещество воздействует внешнее магнитное поле то носители магнетизма данного вещества сориентируются так что направления их магнитных моментов совпадут с направлением внешнего магнитного поля. Мерой изменения магнитного поля в веществе служит величина его магнитной проницаемости μ...
36158. Общие положения амплитудной модуляции (АМ). Основы инженерного расчёта генераторов с АМ смещением. Схемы модуляторов 422.5 KB
  Общие положения амплитудной модуляции (АМ). АМ смещением: принцип, схема, статические и динамические модуляционные характеристики. Энергетические и качественные показатели. Основы инженерного расчёта генераторов с АМ смещением. Схемы модуляторов.
36159. СПОСОБЫ ПУСКА, РЕГУЛИРОВАНИЯ ЧАСТОТЫ ВРАЩЕНИЯ И ТОРМОЖЕНИЯ ЭЛЕКТРОПРИВОДОВ ПОСТОЯННОГО ТОКА 244.51 KB
  Способы пуска электродвигателей постоянного тока влияние против ЭДС обмотки якоря. Способы регулирования частоты вращения электродвигателей постоянного тока. Электрическое торможение двигателей постоянного тока
36160. Способы пуска электродвигателей переменного тока 277.32 KB
  Прямой пуск короткозамкнутых асинхронных двигателей нормального исполнения Прямой пуск короткозамкнутых асинхронных двигателей специального исполнения Реостатный пуск двигателей с фазным ротором Пуск при пониженном напряжении на обмотке статора
36161. HDD-РЕКОРДЕРЫ 157 KB
  К каждой стороне диска на специальных вращающихся кронштейнах коромыслах подводятся магнитные головки с помощью которых и осуществляется запись и считывание данных рис. Поверхности диска должны быть идеально плоскими и тщательно отполированными. Кронштейны с головками могут поворачиваться вокруг оси на которой они закреплены и головки размещенные на их концах могут таким образом устанавливаться на любую дорожку диска. Кронштейн слегка подпружинен и его конец с закрепленными головками в отсутствии вращения диска должен соприкасаться с...
36162. Определение и история SSD 81.22 KB
  Для SSD в настоящее время применяются два типа NANDFlash памяти: SLC Single Level Cell и MLC Multi Level Cell отличающиеся плотностью хранения информации. При подаче на управляющий затвор положительного напряжения инициализация ячейки памяти он будет находиться в открытом состоянии что соответствует логическому нулю рис. Устройство транзистора с плавающим затвором и чтение содержимого ячейки памяти Таким образом наличие или отсутствие заряда на плавающем затворе однозначно определяет состояние транзистора открыт или закрыт при...
36163. Физические характеристики, позволившие получить высокую информационную емкость диска BluRay 90 KB
  Минимальный диаметр b светового пятна в точке фокуса прямо пропорционален длине волны излучения лазера и обратно пропорционален числовой апертуре объектива: где с коэффициент величина которого зависит от уровня световой энергии по которому измеряется диаметр пятна. Сравнительные размеры светового пятна по уровню первого темного кольца Эйри для излучения с длиной волны 780 нм CD 650 нм DVD и 405 нм BluRay приведены на рис. Площадь же светового пятна как известно прямо пропорциональна квадрату его радиуса S = πr2 или диаметра S =...