
- •10 Перевантаження операторiв.
- •10.1 Перевантаження операторів. Загальний підхід.
- •10.2 Перетворення типів.
- •10.3 Перевантаження деяких операторів.
- •10.3.1 Оператор індексування масиву.
- •10.3.2 Перевантаження оператора виклику функції.
- •10.3.3 Оператор доступу до члена класу.
- •10.3.4 Перевантаження операторів інкремента та декремента.
- •10.3.5 Перевантаження операторів управління пам’яттю (new,delete).
- •10.3.6 Перевантаження оператора присвоювання.
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 просто друкується вміст масиву: символьний рядок та кількість його входжень у вхідному потоці.