Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Курс лекцій.doc
Скачиваний:
15
Добавлен:
03.11.2018
Размер:
1.12 Mб
Скачать

10.3 Перевантаження деяких операторів.

10.3.1 Оператор індексування масиву.

В С++ можна перегружати оператор індексування масиву.

Приклад 1:

class PseudoArray {

private:

int val0,val1,val2;

public:

PseudoArray(int v0, int v1, int v2)

{val0=v0;

val1=v1;

val2=v2;}

int GetInf(unsigned i);

int operator [ ] (unsigned i);

};

main()

{PseudoArray pa (10,20,30);

for (int i=0, i<=2 i++);

cout<<"pa["<<i<<]="<<pa[i];}

int PseudoArray : : GetInt(unsigned i)

{switch(i){

case 0:return val0;

case 1:return val1;

case 2:return val2;

default:return val 0;

}

}

int PseudoArray : : operator [ ] (unsigned i)

{return GetInt(i);}

Або в main-функції можемо написати такий фрагмент:

PseudoArray ekz(1,2,3);

cout <<ekz.GetInt(1);

cout <<ekz [1];

Останні два оператори еквівалентні.

Приклад 2.

struct pair {

char * name;

int val;};

class assoc {

pair * vec;

int max;

int free;

public:

assoc (int);

int & operator [ ] (char *);

void print_all ();

};

static pair vec[1000];

assoc :: assoc (int s)

{free=0;

max=(s<16)? s:16

vec=new pair[max];

}

int & assoc :: operator [ ] (char * p)

{register pair * pp;

for (pp=& vec[free]; vec<=pp; pp--)

if (strcmp (p,pp->name)==0) return pp->val;

// ситуацiя,коли в масивi слова немає...

}

void assoc :: print_all ()

{for (int i=o; i<free; i++)

cout <<vec[i]. name <<"i" <<vec[i].val;}

main ()

{const Max=256;

char buf [Max];

assoc vec (512);

while (cin<<buf) vec [buf]++;

vec.print_all ();

}

З прикладу ми бачимо, що iндекси перевантажених масивiв можуть бути довiльними типами даних. В цьому i полягає поняття асоцiативного масиву, тобто за рахунок перевантаженої операцiї iндексування масиву встановлюється взаємно-однозначна вiдповiднiсть мiж множиною "iндексiв" масиву, якi можуть бути даними будь-якого типу та відповідних значень.

10.3.2 Перевантаження оператора виклику функції.

Синтаксично реалізується наступним чином:

<тип> operator( ) (параметри)

Перевантажений оператор виклику функцiї робить об'єкт класу схожим на функцiю, яку можна викликати. При цьому допускається присутнiсть списку параметрiв, якi обчислюються та перевiряються на відповідність компілятором у вiдповiдностi iз звичайними правилами передачi параметрiв.

class TanyClass {

int x;

public:

int operator () (void);

TanyClass(int n) {x=n;}

};

int TanyClass : : operator() (void)

{return x;}

main ()

{TanyClass object=100;

int q=object();

cout <<q;

return 0;}

Перевантаження оператора виклику функції може бути корисною у випадку, коли об'єкт має домiнуючу властивість. Розглянемо приклад. Нехай маємо вже визначений вище клас assoc, у якому оголошений дружній клас a_itеrator:

struct pair {

char * name;

int val;};

class assoc {

friend class a_itеrator;

pair * vec;

int max;

int free;

public:

assoc (int);

int & operator [ ] (char *);

void print.all ();

};

class a_iterator {

assoc * cs;

int i;

public:

a_iterator (assoc & s){cs=&s; i=0;}

pair * operator()

{return (i<сs->free)?cs->vec[i++];0;}

};

main()

{ pair p;

const Max=256;

char buf [Max];

assoc mas(512);

while (cin<<buf) mas[buf]++;

a_iterator next(mas);

while (p=next()) cout<< p->name<<"i"<<p->val;

}

В наведеному прикладі клас a_iterator містить перевантажений оператор виклику функції, який повертає слідуючий елемент динамічного масиву , елементами якого є структури типу pair. Цей масив (в прикладі 512 елементів) утворюється при визначенні екземпляра mas класу assoc та ініціалізується в циклі while (cin<<buf) mas[buf]++; Тіло циклу виконується доти, доки не зустрінеться символ кінця файлу. В останньому операторі while просто друкується вміст масиву: символьний рядок та кількість його входжень у вхідному потоці.