Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
5fan_ru_Obektno-orientirovannoe_programmirovan...doc
Скачиваний:
3
Добавлен:
01.05.2025
Размер:
352 Кб
Скачать
☆

4. Перегрузка операций

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

. - прямой выбор компонента структурированного объекта;

.* - обращение к компоненту через указатель на него;

:: - операция указания области видимости;

?: - условная операция;

sizeof - операция вычисления размера в байтах;

# и ## - препроцессорные операции.

Перегрузка операций выполняется с помощью операций - функций.

Синтаксис объявления прототипа операции – функции:

Тип_возвращаемого значения operator знак_операции

(список параметров операции-функции);

Если принять, что конструкция operator знак_операции есть имя некоторой функции, то прототип операции-функции подобен прототипу обычной функции языка С.

4.1. Перегрузка бинарных операций

Рассмотрим перегрузку бинарных операций на примере простой программы, показанной в листинге 4.1. В этой программе показана перегрузка операций сложения + и присваивания = в классе V_3d, содержащем координаты вектора в трехмерном пространстве.

Листинг 4.1

#include <iostream.h>

class V_3d

{

double x,y,z;

public:

//конструктор по умолчанию

V_3d(){x=0;y=0;z=0;};

//конструктор, принимающий параметры

V_3d(double x1,double y1,double z1)

{ x=x1; y=y1; z=z1; };

//вывод вектора

Void print();

// функция для перегрузки +

V_3d operator +(V_3d t);

// функция для перегрузки =

V_3d operator =(V_3d t);

};

Void main(void)

{

//создание обьектов а, b, d, s класса V_3d

V_3d a(2,3,5); //запускается конструктор с параметрами

V_3d b(5,6,5);

V_3d d,s; // запускается конструктор по умолчанию

cout << "координаты вектора a:\n";

a.print();

cout << "координаты вектора b:\n";

b.print();

d =a+b; //демонстрация перегруженной операции сложения векторов a и b

cout << "\n сумма векторов a и b :\n";

d.print();

s=a; // демонстрация перегруженной операции присваивания

cout << "\n координаты вектора s\n";

s.print();

}

//метод класса для вывода координат вектора

Void v_3d::print()

{

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

}

// определение функции - оператора +

V_3d V_3d::operator +(V_3d t)

{

V_3d c;

c.x=x+t.x; c.y=y+t.y; c.z=z+t.z;

return c;

}

// определение функции - оператора=

V_3d V_3d::operator =(V_3d t)

{

x=t.x;

y=t.y;

z=t.z;

return *this;

}

Эта программа выводит на экран следующие данные:

координаты вектора a:

x= 2 y= 3 z= 5

координаты вектора b:

x= 5 y= 6 z= 5

сумма векторов a и b :

x= 7 y= 9 z= 10

координаты вектора s

x= 2 y= 3 z= 5

Следует обратить внимание на то, что в приведенной программе обе функции-оператора имеют по одному параметру, несмотря на то, что они перегружают бинарный оператор. Это связано с тем, что при перегрузке бинарного оператора один аргумент - указатель this передается функции оператору неявно. Так, строка

d=a+b;

эквивалентна следующему явному вызову операции - функции:

d = a. operator + ( b );

this =&a, т.е. с левым операндом перегруженной бинарной операции по умолчанию связывается указатель this.

Вывод.

При перегрузке бинарной операции именно объект слева от знака операции вызывает функцию-оператор. Объект, стоящий справа от знака операции, передается функции.

4.2. Перегрузка унарных операций

Можно перегрузить унарные операции, такие, как ++ или --. При перегрузке унарных операций с помощью функций – методов класса функция-оператор не имеет параметров. Унарная операция выполняется над объектом, осуществляющим вызов функции-оператора путем неявной передачи указателя this.

Пусть имеется следующее определение класса:

class V_3d

{

int x,y ,z ;

public:

// прототип функции-оператора для перегрузки префиксной операции инкремента

V_3d operator ++ ( );

// прототип функции-оператора для перегрузки постфиксной операции инкремента

V_3d operator ++( int );

// прототипы других функций

//........

}

Где int - фиктивный параметр, указываемый для постфиксной операции, чтобы можно было отличить префиксную операцию от постфиксной, он никак не указывается при вызове.

Определение функции для перегрузки префиксной операции инкремента:

V-3d V_3d :: operator ++( )

{

x ++ ;

y ++ ;

z ++ ;

//возвращает this - указатель на объект, для которого вызвана эта функция-оператор

return *this ;

}

Если затем в программе будет создан объект класса V_3d:

V_3d c ;

То возможно следующее увеличение с:

++ c;

Определение функции для перегрузки постфиксной операции инкремента:

V_3d V_ 3d :: operator ++( int )

{

V_3d tmp ;

tmp = *this ;

x ++;

y ++;

z ++;

// Возвращает старое значение объекта.

return tmp ;

}

Замечание для постфиксной операции:

она увеличивает значение элементов-данных объекта на единицу, но возвращает старое значение объекта.

4.3 Друзья классов

В разделе 3.3 было показано, что механизм управления доступом позволяет выделить общедоступные (public), защищенные (protected) и собственные (private) элементы классов. Защищенные элементы доступны внутри класса и в производных классах. Собственные элементы локализованы в классе и недоступны извне. С помощью общедоступных элементов реализуется взаимодействие класса с любыми частями программы.

Имеется еще одна возможность расширить интерфейс класса. Ее обеспечивают дружественные функции.

Дружественной функцией класса называется функция, которая, не являясь методом класса, имеет право доступа к private и protected элементам класса.

Функция не может стать другом класса “без его согласия”. Для получения прав друга функция должна быть описана в теле класса со спецификатором friend.