67280

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

Лекция

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

На додаток до традиційних перевантажених операторів мова програмування C++ дає змогу перевантажувати і оператор індексації елементів масиву "[]". У мові програмування C++ (з погляду механізму перевантаження) оператор "[]" вважається бінарним.

Украинкский

2014-09-06

49 KB

1 чел.

Лекція № 12

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

   На додаток до традиційних перевантажених операторів мова програмування C++ дає змогу перевантажувати і оператор індексації елементів масиву "[]". У мові програмування C++ (з погляду механізму перевантаження) оператор "[]" вважається бінарним. Його можна перевантажувати тільки для класу і тільки з використанням функції-члена класу. Ось як виглядає загальний формат операторної функції-члена класу operator[]().

тип ім'я_класу::operator[](int індекс)

{

//...

}

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

    Припустимо, нехай створено об'єкт ObjA, тоді вираз ObjA[3] перетвориться в такий виклик операторної функції operator[]():

ObjA.operator[](3);

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

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

Приклад1.  Демонстрація механізму перевантаження оператора індексації елементів

                   масиву "[]"

const int size = 3;

class aClass

{

int aMas[size];

public:

aClass() { for(int i=0; i<size; i++) aMas[i] = i*i; }

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

};

void main()

{

aClass ObjA;

cout << "aMas[2]= " << ObjA[2] << endl;                   // Відображає число 4

cout << "Znachennja elementiv mas <A>:" << endl;

for(int i=0; i<3; i++)

 cout << "aMas[" << i << "]= " << ObjA[i] << endl;

}

   Внаслідок виконання ця програма відображає на екрані такі результати:

a[2]= 4

Значення елементів масиву <A>:

a[0]= 0

a[1]= 1

a[2]= 4

 

   Ініціалізація масиву aMas за допомогою конструктора (у цій і наступній програмах) здійснюється тільки з ілюстративною метою. У цьому коді програми функція operator[]() спочатку повертає значення 3-го елемента масиву aMas. Таким чином, вираз ObjA[2] повертає число 4, яке відображається настановою cout. Потім у иклі виводяться усі елементи масиву.

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

Приклад2.  Демонстрація механізму перевантаження оператора індексації елементів

                   масиву "[]" як зліва, так і праворуч від оператора присвоєння

const int size = 3;

 

class aClass

{

 int aMas[size];

public:

aClass() { for(int i=0; i<size; i++) aMas[i] = i*i; }

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

};

 

int main()

{

  aClass ObjA;

  cout << "Znachennja elementiv mas <A>:" << endl;

  for(int i=0; i<3; i++)

 cout << "aMas[" << i << "]= " << ObjA[i] << endl;

 

  ObjA[2] = 25;       // Оператор "[]" знаходиться зліва від оператора

                            присвоєння "=".

 cout << endl << "aMas[2]= " << ObjA[2]; // Тепер відображається число 25.

}

   Внаслідок виконання ця програма відображає на екрані такі результати:

Значення елементів масиву <A>:

a[0]= 0

a[1]= 1

a[2]= 4

 

a[2]= 25

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

    Одна з наявних переваг перевантаження оператора індексації елементів масиву "[]" полягає у тому, що за допомогою нього ми можемо забезпечити реалізацію безпечної індексації елементів масиву. Як уже зазначалося вище, у мові програмування C++ можливий вихід за межі масиву у процесі виконання програми без відповідного повідомлення (тобто без генерування повідомлення про динамічну помилку). Але,  якщо  створити  клас,  який містить масив,  і надати  доступ  до цього масиву тільки через перевантажений оператор індексації елементів масиву "[]", то в процесі виконання програми можливе перехоплення індексу, значення якого вийшло  за  дозволені  межі.  Наприклад,  наведений  нижче  код  програми (в  основу якої покладений програмний код попередньої) оснащена  засобом контролю потрапляння індексу масиву в допустимий інтервал його перебування.

Приклад3.  Демонстрація прикладу організації безпечного масиву

const int size = 3;

 

class aClass

{  

 int aMas[size];

public:

aClass() { for(int i=0; i<size; i++) aMas[i] = i*i; }

 int &operator[](int i);

};

 

  // Забезпечення контролю потрапляння індексу масиву

  // в допустимий інтервал його перебування.

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

{

 if(i<0 || i> size-1)

{

 cout << endl << "Znachennja indeksy " << i <<

            " vuhodut za me*i dopystumogo intervaly" << endl;

 //getch(); exit(1);

}

 return aMas[i];

}

 

void main()

{

aClass ObjA;

cout << "Znachennja elementiv mas <A>:" << endl;

 for(int i=0; i<3; i++)

 cout << "aMas[" << i << "]= " << ObjA[i] << endl;

ObjA[2] = 25;           // Оператор "[]" знаходиться в лівій частині.

cout << endl << "aMas[2]= " << ObjA[2];   // Відображається число 25.

ObjA[3] = 44;      // Виникає помилка тривалості виконання, оскільки

             // значення індексу 3 виходить за межі допустимого інтервалу.

}

   Внаслідок виконання ця програма відображає на екрані такі результати:

Значення елементів масиву <A>:

a[0]= 0

a[1]= 1

a[2]= 4

 

a[2]= 25

Значення індексу 3 виходить за межі масиву.

   У процесі виконання настанови

ObjA[3] = 44;

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


 

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

25623. Внезародышевые органы 43.5 KB
  Амнион временный орган обеспечивающий водную среду для развития зародыша. В эмбриогенезе человека он появляется на второй стадии гаструляции сначала как небольшой пузырек дном которого является первичная эктодерма эпибласт зародыша. Желточный мешок наиболее древний в эволюции внезародышевый орган возникший как орган депонирующий питательные вещества желток необходимые для развития зародыша.
25624. Зрительная сенсорная система. Орган зрения 61 KB
  В передней части глаза склера переходит в покрытую многослойным плоским эпителием прозрачную роговицу. Наружная фиброзная оболочка глазного яблока к которой прикрепляются наружные мышцы глаза обеспечивает защитную функцию. Внутренняя чувствительная оболочка глаза сетчатка сенсорная рецепторная часть зрительного анализатора в которой происходят под воздействием света фотохимические превращения зрительных пигментов фототрансдукция изменение биоэлектрической активности нейронов и передача информации о внешнем мире в подкорковые...
25626. Гистогенез и органогенез на 2 и 3 неделе развития 26.5 KB
  Коммутирование ограничение возможных путей развития клеток. Оно совершается последовательно: сначала преобразуются крупные участки генома детерминирующие наиболее общие свойства клеток а позднее более частные свойства. Дифференцировка это изменения в структуре клеток связанные с их функциональной специализацией обусловленные активностью определенных генов. В развивающемся организме дифференцировка сопровождается определенной организацией или размещением специализирующихся клеток что выражается в установлении определенного плана...
25627. Гистогенез и органогенез 22 KB
  4 неделя Углубление желточной складки образование желточного стебля и приподнятие зародыша в полости амниона. Замыкание нервной трубки и формирование переднего невропора к 25 сут и заднего невропора к 27 сут образование нервных ганглиев; закладка легкого желудка печени поджелудочной железы эндокринных желез аденогипофиза щитовидной и околощитовидных желез. Образование ушной и хрусталиковой плакод первичной почки мезонефроса. Образование зачатков верхних и нижних конечностей 4 пар жаберных дуг.
25628. Гладкие мышечные ткани 29.5 KB
  Стволовые клетки и клеткипредшественники в гладкой мышечной ткани на этапах эмбрионального развития пока точно не отождествлены. Поверх чехликов из базальной мембраны между миоцитами проходят эластические и ретикулярные волокна объединяющие клетки в единый тканевой комплекс. Ретикулярные волокна проникают в щели на концах миоцитов закрепляются там и передают усилие сокращения клетки всему их объединению. Поэтому после поступления нервного импульса медиатор распространяется диффузно возбуждая сразу многие клетки.
25630. Дифференцировка первичной эктодермы 39 KB
  Меньшая часть эктодермы расположенная над хордой нейроэктодерма дает начало дифференцировке нервной трубки и ганглиозной пластинки. Нейруляция процесс образования нервной трубки протекает по времени неодинаково в различных частях зародыша. Замыкание нервной трубки начинается в шейном отделе а затем распространяется кзади и несколько замедленнее в краниальном направлении где формируются мозговые пузыри. Из нервной трубки образуются нейроциты и нейроглия головного и спинного мозга сетчатки глаза и органа обоняния.
25631. Диффузная эндокринная система 32 KB
  Среди одиночных гормонпродуцирующих клеток различают две самостоятельные группы: I нейроэндокринные клетки APUDсерии нервного происхождения; II клетки не нервного происхождения. Эти клетки характеризуются способностью поглощать и декарбоксилировать предшественники аминов англ. Согласно современным представлениям клетки APUDсерии развиваются из всех зародышевых листков и присутствуют во всех тканевых типах: 1 производные нейроэктодермы {нейроэндокринные клетки нейросекреторных ядер гипоталамуса эпифиза мозгового вещества...