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;

}

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


 

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

25195. Знання як особлива форма освоєння світу 27.5 KB
  Пізнання це такий процес що спрямований на отримання знання. Пізнання має багато модусів оскільки людина відноситься до світу у різних площинах і пізнає його у різних ракурсах. Тому можна виділяти наукове пізнання етичне релігійне філософське мистецьке та інші. Пізнанням є таке відношення до світу в якому людина змінює себе за допомогою світу.
25196. Пізнання як особлива форма освоєння світу 25 KB
  Пізнання як особлива форма освоєння світу Якщо дуже просто то пізнання – це процес взаємодії суб’єкта та об’єкта що своїм результатом має знання. Існують різні способи пізнання а отже й різні види знання. Поряд із різноманітністю видів знань існує величезна кількість поглядів на саму природу пізнання. Говорять про абстрактне і конкретне пізнання повне і неповне наукове і філософське тощо.
25197. Концепції комунікативно-структурованого життєсвіту за Ю.Габермасом 35 KB
  Габермас виходить з концепції суспільної еволюції де суспільний розвиток постає у формі руху від родовогоархаїчного до традиційногодержавноорганізованого а потім до модерногокапіталістичного суспільства. Концепція життєсвіту дістає своє втілення в архаїчних суспільствах де структури нормативної інтеграції опосередковані мовленнєвою комунікацією водночас становлять системні структури. Системні механізми в цих суспільства невіддільні від соціальноінтегративних інституцій заснованих на життєвому світі. За умов традиційного...
25198. Пізнання та інтерес Техніка та наука як ідеологія Теорія комунікативної дії 1981 Моральна свідоміст 32.5 KB
  Концепція комунікативноструктурованого життєвого світу Габермаса Осн. Продовжуючи традицію внутрішнього взаємозв'язку між структурами життєвого світу і структурами мови традицію що сягає ще філософії Гумбольдта Г. зауважує що для самого життєвого світу мова і культура є конститутивними .досліджує шлях уречевлення комунікації визначаючи його як роз'єднання системи і життєвого світу.
25199. Поняття феномену в феноменологічній філософії 24 KB
  Він розрізняв даності зовнішнього досвіду фізичні феномени та безпосередньо очевидні психічні феномени які інтенційно містять у собі весь предмет. Феномени не подвоюють світ як деякі це вважають. Навпаки феномени показують виявляють себе як деяку цілісно схоплену одиницю.
25200. М. Вебер «Протестантська етика та дух капіталізму» 35 KB
  Вебер Протестантська етика та дух капіталізму М. Вебер – один з найвизначніших соціологів автор роботи Протестантська етика та дух капіталізму 1907 яка вважається однією з найкращих з аналізу причин виникнення сучасного капіталізму. Щодо духу капіталізму то під ним Вебер розуміє комплекс зв’язків що існують в історичній дійсності які ми розглядаємо як єдине ціле під кутом їх культурного значення. Риси капіталізму можна побачити ще в Древньому Китаї Індії Вавилоні.
25201. Суперечка між західниками та слов’янофілами 26.5 KB
  Суперечка між західниками та слов’янофілами західники – виступали за ліквідацію кріпосного права і розвиток Росії за західним взірцем Герцен Огарев розвиток ідей Просвітництва слов’янофіли – обґрунтування необхідності особливого порівняно з західноєвропейським самобутнього шляху розвитку Росії Киреевский Хомяков основою суспільного життя вважали релігію а саме православ’я Лише народи що сповідують православ’я і перш за все росіяни можуть розраховувати на прогрес а інші народи – лише тією мірою якою вони сприймуть православну...
25202. Емпіризм і Раціоналізм у філософії Нового часу 26.5 KB
  Емпіризм – філософський напрям що визнає чуттєвий досвід джерелом знань і вважає що зміст знання може бути представлен в досвіді або зводитись до нього. Емпіризм зіштовхнувся з труднощами виокремлення вихідних компонентів досвіду і реконструкції на цій основі усіх видів і форм знання. Його девізом було знання сила€ тому головними методами пізнання він вважав спостереження аналіз експеримент порівняння. Джерелом пізнання людини є враження відчуттів які виникають під впливом матеріальних об’єктів.
25203. Філософія неогегельянства 28.5 KB
  Центральний пункт гегелівської діалектики – вчення про протилежності оцінюється як хибне МакТаггарт. Абсолютний дух розглядається як сукупність індивідуальних свідомостей МакТаггарт як вища форма індивідуальності Бозанкет.