Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Case 0: return v0; //break не нужен

Поиск

case 1: return v1; //

case 2: return v2; //

case 3: return v3; //

default: return v0;

}

}

int PArr::operator[] (unsigned i) {

return GetInt(i);

}

Несмотря на простоту, класс PseudoArray содержит все необходимые компоненты для перегрузки операто­ра индексирования массива. В классе объявляются четыре закрытых целочисленных члена в строках 5-8. В строке 13 объявляется функция-член operator[] с одним беззнаковым параметром. Параметр служит индексом в массиве и может иметь произвольный тип.

В строке 12 демонстрируется обычный способ доступа к закрытым данным класса с помощью функции-члена GetlntO, возвращающей одно из целочисленных значений класса. Вы можете объявить объект класса и отобразить второе значение с помощью следующих операторов:

PArray ра(10, 20, 30, 40);

cout «"Value #2 == " «pa.Getlnt(i);

// Вызов функции-члена

Это обычный способ "добраться" к закрытым членам класса. Поскольку в классе перегружен оператор ин­дексации, вы также можете использовать следующий оператор:

cout «"Value #2 == " «ра[1];

// pa используется в качестве массива

В строке 21 приводится еще один пример. Выражения ра[1] и ра[2], оказывается, обеспечивают доступ к массиву несмотря на то, что указатель ра в действительности ссылается на объект класса. Перегрузка операто­ра индексации дает возможность использовать в массиве индексацию (удобный и ясный способ доступа к не­скольким значениям) вместо вызова функции-члена для объекта класса.

Имейте в виду, что индексы перегруженных массивов могут быть произвольными типами данных. Напри­мер, вы можете заменить строку 13 на:

int operator[](char с);

и затем использовать символьные индексы, подобные символам от 'А' до 'D', для индексации массива с начальным индексом 'А', в отличие от обычных массивов в С и C++, в которых используются целочисленные индексные значения, начинающиеся с нуля. По сути, перегружая [] и используя символы в качестве индексов, вы устанавливаете соответствие между множеством символов и множеством значений, создавая тем самым так называемый ассоциативный массив. Вы можете реализовать функцию-член перегрузки оператора [] следую­щим образом:

int PseudoArray::operator[](char с)

return Getlnt(c - 'A'); }

Затем вы можете использовать символьную переменную в качестве индекса массива. Например, после вне­сения предыдущих изменений замените строки 20-21 на следующие:

for (char с = 'A'; c<='D'; с++)

cout «"ра[" «с «"] == " «ра[с] «'\n';

 

Оператор вызова функции

Перегрузка вызова функции operator() делает объект класса похожим на функцию, которую можно вы­звать.

Перегруженная функция operator() может возвращать значения заданных типов или вовсе ничего не возвращать.

В ней также могут объявляться параметры.

Она не может быть статическим членом класса.

Пример4.20 класса с перегруженным оператором вызова функции, возвращающим целочисленное значение:

#include <iostream.h>

#include <conio.h>

class TAClass {

int х;

public:

//Перегруженная функция-член

int operator() (void);

TAClass (int n) { x = n; } };

//В классе TAnyClass перегружается //оператор вызова функции с //помощью объявления int //operator()(void);

//Можно заменить void списком //необходимых параметров. //Перегруженная функция-член

int TAClass::operator()(void)

{return x; }

В этом примере функция operatorO возвращает целочисленные значения члена х объекта TAClass.

main() {clrscr();

TAClass object = 100;

int q = object(); // вызов функции!

//выполняется оператор

// object. Operator()();

cout << q;

getch();

return 0; }

 

Второй оператор похож на вызов функции с именем objectO, но на самом деле выполняется оператор object. Operator()();.

 

 

Оператор доступа к члену класса

Унарный оператор доступа к члену класса -> перегружается как operator->().

Он не м.б. статичес­кой функцией-членом класса.

Можно перегрузить -> для класса TAClass следующим образом:

//Пример 4.21

//4_22

#include <iostream.h>

#include <conio.h>

class TAClass {

int x, y;

public:

TAClass(int xx, int yy)

{ x = xx; y = yy; }

TAClass* operator->();

//Функция-член operator->() //возвращает объект, ссылку или //указатель на объект класса.

//В данном случае возвращает //указатель на класс TAClass.

int GetX(void) { return x; }

int GetY(void) { return y; }

};

TAClass* TAClass:: operator->()

{

cout << "\n Доступное данное: ";

//указатель, ссылающийся на объект, //для которого была вызвана //функция-член

return this;

}

Main()

{

TAClass t(100, 200);

cout << t->GetX() << '\n';

cout << t->GetY() << '\n';

// На самом деле вып-ся так:

//cout«(t.operator->())->GetX() //«'\n';

//cout«(t.operator->())->GetY() //«'\n';

getch();

return 0;

}

 

 

Результат:

Accessing member: 100

Accessing member: 200

 

Функция-член operator->() должна возвращать объект, ссылку или указатель на объект класса. В данном I случае она возвращает указатель на класс TAnyClass.

Оператор реализуется следующим образом:

I

TAClass* TAClass::operator->()

{

cout «"\nAccessing member: ";

return this;

}

В данном примере демонстрируется использование перегрузки оператора -> в качестве отладочного трюка [ Перегруженный оператор выводит короткое сообщение перед тем, как вернуть указатель this, ссылающийся на объект, для которого была вызвана функция-член. В основной программе перегруженный оператор может применяться для объектов класса TAClass следующим образом:

main()

{

TAnyClass t(100, 200);

cout «t->GetX() «'\n';

cout «t->GetY() «'\n'

return 0;

}

В двух операторах вывода в поток используется перегруженный оператор -> для доступа к функциям-чле­нам GetXO и GetY() объекта t класса TAnyClass, На самом деле, эти операторы выполняются так, как приве­денные ниже:

cout «(t.operator->())->GetX() «'\n';

cout «(t.operator->())->GetY() «'\n';

Поэтому программа отобразит метки перед значениями, возвращаемыми функциями GetXO и GetY():

Accessing member: 100

Accessing member: 200

 

Операторы инкремента и декремента

В ранних версиях C++ было невозможно определить отдельные перегруженные операции для постфиксных и префиксных операторов ++ и —.

Пример 4.23

class TAClass {

int x;

public:

TAnyClass(int xx) { x = xx; }

int operator++() { return x++;}

int operator++(int) { return x++;}

int operator--() { return ++x; }

int operator--(int) { return ++x;}

int GetX(void) < return x; }

Функция-член operator++() определяет префиксный оператор инкремента для объекта типа TAnyClass; эта функция не имеет параметров. Функция-член operator++(int) определяет постфиксный оператор инкремента для объекта типа TAnyClass; C++ присваивает нуль единственному целочисленному параметру.

Демонстрационные функции реализуются встраиваемыми, однако они могут реализоваться и отдельно. Для объекта v типа TAnyClass выражение ++v вызовет перегруженный префиксный оператор ++. В действи­тельности выполняется оператор x.operator++();. Выражение v++ вызовет перегруженный постфиксный опе­ратор ++ и выполнится, как x.operator++(0);. Операторы декремента работают аналогичным образом.

 

main() {

TAnyClass t(100);

cout «"t == " «t.GetXO <<t.GetX() <<”; ++t<<’\n’;

cout «"t == " «t.GetX() << t.GetX() <<”; t++<<’\n’;

cout «"t == " «t.GetX() << t.GetX() <<”; --t<<’\n’;

cout «"t == " «t.GetX() << t.GetX() <<”; t--<<’\n’;

}

//4_23

#include <iostream.h>

#include <conio.h>

class TAClass {

int x;

public:

TAClass(int xx) { x = xx; }

int operator++()

{ return ++x;};

int operator++(int)

{ return x++;}

Int operator--()

{ return --x; }

Int operator--(int)

{ return x--;}

int GetX(void) { return x;}

};

main() {

TAClass t(100);

clrscr();

cout<<"t=="<<t.GetX() <<";++t==" << ++t<<"\n";

cout<<"t=="<<t.GetX()<< ";t++==" << t++<<"\n";

cout<<"t ==" << t.GetX() << ";--t==" << --t<<"\n";

cout<<"t=="<<t.GetX()<<";t--==" << t--<<"\n";

getch();

return 0;

}

Результат:

t=101; ++t=101

T=102; t++=101

T=101; --t=101

T=100; t--=101

Другие вопросы, касающиеся перегрузки операторов

Получив некоторое представление о перегрузке операторов, необходимо иметь в виду следующие факты.

• C++ "не понимает" семантики перегруженного оператора. Вы должны обеспечить осмысленные функции перегрузки операторов.

• C++ не может выводить сложные операторы из простых. В классе, в котором объявлены функции пере­грузки операторов operator*() и operator=(), C++ не сможет вычислить выражение а *= b до тех пор, пока вы не перегрузите operator*=().

• Никогда не изменяйте синтаксис перегруженных операторов. Бинарные операторы должны оставаться би­нарными, унарные — унарными. Например, нельзя создать унарное деление, поскольку такой встроенной возможности в C++ не существует.

• Нельзя изобретать новые операторы. Вы можете перегружать только операторы, перечисленные в табл. 15.1.

• Нельзя перегружать символы препроцессора # и ##.



Поделиться:


Последнее изменение этой страницы: 2016-08-01; просмотров: 244; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.117.192.205 (0.01 с.)