Перегрузка унарных операторов 


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



ЗНАЕТЕ ЛИ ВЫ?

Перегрузка унарных операторов



Унарным операторам, подобным унарному плюсу и унарному минусу, необходим только один аргумент.

Вы можете перегрузить эти и другие унарные операторы с помощью трюка, аналогичного проиллюстрирован­ному в предыдущем разделе.

Как и в случае с бинарными операторами, вы можете объявить функцию перегрузки унарного оператора другом или членом класса.

В объявлении дружественной функции перегрузки унарного оператора необходим только один параметр, имеющий тип класса (только одно значение, над которым надо произвести действия). Например, добавьте следующее объявление в STROPS2.CPP (листинг 4.5) прямо над private: в строке 6:

friend long operator-(TStrOp a);

Даже несмотря на то что в строке 13 перегружен оператор вычитания, конфликтов не возникнет, посколь­ку в новом объявлении задан один параметр. Функция-член в строке 13 получает скрытый параметр this.

#include <iostream.h>

#include <stdlib.h>

#include <string.h>

#include <conio.h>

class TStrOp {

friend long operator-(TStrOp a);

private:

char value[12];

public:

TStrOp() { value[0] = 0; }

TStrOp(const char *s);

long GetValue(void)

{ return atol(value); }

long operator+(TStrOp b);

long operator-(TStrOp b);

};

Main()

{

TStrOp a = "1234";

TStrOp b = "4321";

cout << "\nValue of a == " <<a.GetValue();

cout <<"\nValue of b == " <<b.GetValue();

cout <<"\na + b + 6 == "<< (a+b+6)<<"\n";

cout <<"\na - b + 10 == " << (a-b+10)<<"\n";

cout <<"\n-a== "<< (-a)<<"\n";

getch();

return 0;

}

TStrOp:: TStrOp(const char *s) {

strncpy(value, s, 11);

value[11] = 0;

}

long TStrOp::operator+(TStrOp b) {

return (atol(value) + atol(b.value));

}

long TStrOp::operator-(TStrOp b)

{ return (atol(value) - atol(b.value));

}

long operator-(TStrOp a){

return (-atol(a.value));

}

 

Но­вая функция, не являющаяся членом класса, не получит указателя this.

Для реализации новой функции пере­грузки унарного минуса, не являющейся членом класса, добавьте следующие строки после функции main():

long operator-(TStrOp a)

return - atol(a.value);

Поскольку унарный- оператор "минус" — друг класса, оператор return имеет непосредственный доступ к закрытому члену параметра а, имеющему тип класса TStrOp. Теперь функция закончена, и компилятор может вычислить выражения, использующие унарный минус и объекты этого типа класса. Например, добавьте сле­дующий оператор в функцию main О (лучше всего после строки 20):

cout «"\n-a == " << -а;

 

Скомпилируйте и запустите на выполнение модифицированную программу. Как вы видите, выражение -г заменено на операцию отрицания длинного целого представления строкового члена а. Вы научили C++ выполнять операцию отрицания над длинными целыми значениями, представленными в строковой форме!

можно объявить перегруженные унарные операторы функциями-членами.

Беря за основу первоначальную копию STROPS2.CPP, добавьте следующее объявление над строкой 14 (перед закрывающей скобкой класса TStrOp):

long operator-(void);

#include <iostream.h>

#include <stdlib.h>

#include <string.h>

#include <conio.h>

class TStrOp {

private:

char value[12];

public:

TStrOp() { value[0] = 0; }

TStrOp(const char *s);

long GetValue(void)

{ return atol(value); }

long operator+(TStrOp b);

long operator-(TStrOp b);

long operator-(void);

};

Main()

{

TStrOp a = "1234";

TStrOp b = "4321";

cout << "\nValue of a == " <<a.GetValue();

cout <<"\nValue of b == " <<b.GetValue();

cout <<"\na + b + 6 == "<< (a+b+6)<<"\n";

cout <<"\na - b + 10 == " << (a-b+10)<<"\n";

cout <<"\n-a== "<< -a<<"\n";

getch();

return 0;

}

TStrOp:: TStrOp(const char *s) {

strncpy(value, s, 11);

value[11] = 0;

}

long TStrOp::operator+(TStrOp b) {

return (atol(value) + atol(b.value));

}

long TStrOp::operator-(TStrOp b)

{ return (atol(value) - atol(b.value));

}

long TStrOp::operator-(void){

return (-atol(value));

// аналогично -atol(this->value)

}

Это объявление функции-члена похоже на объявление предыдущей дружественной унарной функции.

По­скольку все функции-члены получают указатель this, новая функция-член operator-() объявляется без пара­метров и оперирует непосредственно длинным целым эквивалентом значения this->value. Это демонстрируется в реализации функции, которую вы можете вставить после функции main():

long TStrOp::operator-(void)

return -atol(value); // аналогично -atol(this->value)

Перегруженная функция-член возвращает длинное целое значение value с обратным знаком. Его можно ис­пользовать в выражениях, подобных следующему, которые можно вставить в функцию main():

cout «"\п-а == " << -а;

Преобразование типов

можно определить свои собственные правила преобразования типов данных для автоматического пре­образования объектов в другие типы. Например, предположим, что объявили и инициализировали объект класса TStrOp из STROPS2.CPP (листинг 15.5) следующим образом:

TStrOp myValue = "9876";

...

Класс TStrOp запоминает строку, которая может использоваться как эквивалент длинного целого значения в операциях сложения и вычитания. можно логически попытаться присвоить объект myValue переменной длинного целого типа:

long х = myValue; //???

Конечно, этот оператор не скомпилируется, поскольку в классе TStrOp не предусмотрено преобразование строки в длинное целое значение.

Решение этой проблемы заключается в использовании перегрузки операции преобразования типов для преобразования объекта класса TStrOp к другому типу данных.

Операторы преобразования принимают форму оператора TYPE, где TYPE — тип данных, к которому необходимо преобразовать объект класса.

Например, для задания правила преобразования типа объектов класса TStrOp в длинное целое надо вставить следующую встраиваемую функцию внутрь открытой секции класса:

operator long() { return atol(value); }

#include <iostream.h>

#include <stdlib.h>

#include <string.h>

#include <conio.h>

class TStrOp {

private:

char value[12];

public:

TStrOp() { value[0] = 0; }

TStrOp(const char *s);

long GetValue(void)

{ return atol(value); }

long operator+(TStrOp b);

long operator-(TStrOp b);

long operator-(void);

//оп-ор преобразования типов

operator long(){return atol(value);}

};

Main()

{

TStrOp a = "1234";

TStrOp b = "4321";

long x=a;

cout << "\nValue of a == " <<a.GetValue();

cout <<"\nValue of b == " <<b.GetValue();

cout <<"\na + b + 6 == "<< (a+b+6)<<"\n";

cout <<"\na - b + 10 == " << (a-b+10)<<"\n";

cout <<"\n-a== "<< -a<<"\n";

cout <<"\n x== "<< x<<"\n";

getch();

return 0;

}

TStrOp:: TStrOp(const char *s) {

strncpy(value, s, 11);

value[11] = 0;

}

long TStrOp::operator+(TStrOp b) {

return (atol(value) + atol(b.value));

}

long TStrOp::operator-(TStrOp b)

{ return (atol(value) - atol(b.value));

}

long TStrOp::operator-(void){

return (-atol(value));

}

Подобное использование оператора ключевого слова специально обеспечивается в C++ для создания новых правил преобразования типов. С новым правилом появилась возможность присвоить объект типа TStrOp пере­менной длинного целого типа, передав объект TStrOp в качестве параметра функции, возвращающей длинное целое, и т.д.

Оператор индексирования массива

можно перегрузить оператор индексирования массива [] для реализации доступа к данным-членам класса, подобного доступу к элементам массива, даже если эти данные имеют вид отдельных членов или спи­ска.

пример (листинг 4.6) демонстрируется перегрузка оператора [] для класса, запоминающего четыре целочисленных значения в виде отдельных данных-членов.

#include <iostream.h>

#include <conio.h>

class PArr{

private:

int v0;

int v1;

int v2;

int v3;

public:

PArr(int vl0, int vl1,int vl2, int vl3) { v0 = vl0; v1 = vl1;v2 = vl2; v3 = vl3;};

int GetInt(unsigned i);

int operator[](unsigned i);

};

Main()

{ clrscr();

PArr pa(10, 20, 30, 40);

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

cout<< "pa[" <<i <<"] == "<<pa[i] <<"\n";

getch();

return 0;

}

Int PArr::GetInt(unsigned i)

{

switch (i) {



Поделиться:


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

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