Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
недостающая теория.doc
Скачиваний:
8
Добавлен:
22.09.2019
Размер:
619.01 Кб
Скачать

5.2.6. Перегрузка оператора ()

Оператор вызова функции можно доопределить, как и любой другой оператор. Как и в предыдущем случае, оператор () необходимо перегружать только с помощью компоненты-функции, использование friend-функции запрещено. Общая форма функции operator()() имеет вид

тип_возвр_значения имя_класса::operator ()(список_аргументов)

{ тело функции}

#include <iostream>

using namespace std;

class matr

{ int **m,a,b;

public:

matr(int,int);

~matr();

int operator()(int,int); // перегрузка оператора ()

int operator()(int); // перегрузка оператора ()

};

matr::matr(int i,int j): a(i),b(j) // конструктор

{ i=0;

m=new int *[a];

for(int k=0; k<a; k++)

{ *(m+k)=new int[b];

for(int n=0; n<b; n++)

*(*(m+k)+n)=i++; // заполнение m числами 0,1,2,3, …a*b

}

}

matr::~matr() // деструктор

{ for(int k=0; k<a; k++)

delete [] m[k]; // освобождение памяти для k-й строки

delete [] m; // освобождение памяти для всего массива

} // указателей m

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

{ if (i<0 || i>=a || j<0 || j>=b)

{ cerr<<"выход за пределы матрицы ";

return m[0][0]; // например, при этом возврат m[0][0]

}

return m[i][j]; // возврат требуемого элемента

}

int matr::operator()(int i)

{ if (i<0 || i>=a*b)

{ cerr<<"выход за пределы массива ";

return **m; // как и выше возврат m[0][0]

}

return m[i/b][i%b]; // возврат требуемого элемента

}

int main()

{ matr mt(3,5);

cout << mt(2,3) << endl;

cout << mt(3,2) << endl; // попытка получить элемент из 3-й строки

cout << mt(3) << endl;

return 0;

}

Результаты работы программы:

13

выход за пределы массива 0

6

Конструктор класса matr динамически выделяет и инициализирует память двухмерного массива. Деструктор разрушает массив автоматически при завершении программы. В классе matr реализованы две функции operator(): первая получает два аргумента (индексы в матрице), вторая получает один аргумент (порядковый номер элемента в матрице). Обе функции возвращают либо требуемый элемент, либо элемент m[0][0] при попытке выхода за пределы матрицы.

5.2.7. Перегрузка оператора ->

Оператор -> доступа к компонентам объекта через указатель на него определяется как унарный постфиксный.

Ниже приведен простой пример программы перегрузки оператора ->:

#include <iostream>

#include <iomanip>

using namespace std;

#include "string.h"

class cls_A

{ char a[40];

public:

int b;

cls_A(char *aa,int bb): b(bb) // конструктор

{strcpy(a,aa);}

char *put_A() {return a;}

};

class cls_B

{ cls_A *p; // указатель на объект класса cls_A

public:

cls_B(char *aa,int bb) {p=new cls_A(aa,bb);} // конструктор

~cls_B() {delete p;} // деструктор

cls_A *operator->(){return p;} // функция перегрузки ->

};

int main()

{ cls_B ptr("перегрузка оператора -> ",2); // объект класса cls_B

cout << ptr->put_A() << setw(6) << ptr->b <<endl; // перегрузка ->

cout << (ptr.operator->())->put_A() << setw(6)

<< (ptr.operator->())->b <<endl;

cout << (*ptr.operator->()).put_A() << setw(6)

<< (*ptr.operator->()).b <<endl;

}

Результат работы программы:

перегрузка оператора -> 2

перегрузка оператора -> 2

перегрузка оператора -> 2

В приведенной программе инструкции ptr->put_A() и ptr->b приводят к перегрузке операции ->, т.е. позволяют получить адрес указателя на компненты класса cls_A для (из) объекта ptr. Таким образом, инструкция ptr->b соответствует инструкции (ptr.p)->b. Следующие далее две группы инструкций также верны, но не являются примером перегрузки оператора ->, а только приводят к явному вызову функции operator-> - компоненты класса cls_B.

В целом доопределение оператора -> позволяет использовать ptr с одной стороны как специальный указатель (в примере для класса cls_A), а с другой стороны как объект (для класса cls_B).

Специальные указатели могут быть доопределены следующим образом:

cls_A &operator*(){return *p;}

cls_A &operator[](int index){return p[index];}

а также доопределение может быть выполнено по отношению к большинству рассмотренных ранее операций (+, ++ и др.).