Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование на C / C++ / Лекции по объектно-ориентированному программированию (С++).doc
Скачиваний:
150
Добавлен:
02.05.2014
Размер:
226.82 Кб
Скачать

Дружественные функции.

В СИ++ есть функции, которые могут дружить с классами. Эта “дружба” позволяет получить доступ заранее определенным функциям к любому полю данных класса, независимо от спецификатора доступа (private, protected и т.д.). Общее название таких функций – дружественные. Их используют, когда надо использовать поля данных разных классов с входом механизма членов функций. С помощью этих функций можно расширить количество способов взаимодействия с классами. Дружить с классом можно только с его разрешения.

Для этого в теле класса перед объявлением функции надо поставить слово friend.

class { ------ // ------ // ------

friend тип_возвр_значения имя_функции (список параметров);

------ // ------ // ------

}; // конец определения

тип_возвр_значения имя_функции (список параметров)

{ /* тело дружеств. функции */ }

# include <iostream.h>

class FR

{private : int vol 1, vol 2;

friend void drag (FR*, int); // функция friend - не метод класса.

тип тип

public : FR (int par1 =Ø, int par2 =Ø)

{vol 1 = par1;

vol 2 = par2;}

void show ( );

void set (int);

};

void FR :: show ( )

{cout << ” \ n Значение поля данных = “<<endl;

cout << “vol 1 = “<<vol 1<<” vol 2 =”<<vol 2;

} // различный способ доступа к полям класса

void FR :: set (int s)

{vol 2 = s;}

void drag (FR*par, int s) // дружественная функция

{par → vol 2 = s;}

void main ( )

{FR ob (1Ø);

ob. show ( );

drag (& ob, 1111);

ob. show ( );

ob. set (1112);

ob. show ( );

}

За исключением возможности доступа к закрытым полям класса дружественных функции ничем не отличаются от обычных функций. Так как для них не определены уровни доступа, то объявление можно помещать в любом месте класса, даже после private и protected. Для них не формируется указатель this.

К полям данных FR надо использовать явный указатель на объект (для доступа дружественных функций). В член функции вместо строки мы используем vol 2 = s → vol 2 = s.

Одна и та же функция может быть объявлена другом в нескольких классах.

class Y; // неполное объявление класса, для использования class Y в качестве параметра, до его описания (Y еще не определен).

class X {friend void fr_all (X,Y); // где X и Y – типы параметров функции.

… … … ... … … };

class Y {friend void fr_all (X,Y);

------ // ------ // ------ };

void fr_all (X par1, Y par2)

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

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

Механизм основан на возможности применения стандартных операций к операндам, тип которых не является стандартным, кроме :

( · ), ( .* ), ( :: ), ( ?: ), ( # ), ( ## ), ( = ), ( [ ] ), ( ( ) ), ( → ).

Нельзя использовать “свои ” символы.

тип_возвр_значения operator знак_операции (параметры) // operator – вместо имени

{ ... ... ... ... ... ...

операторы … … …}

Матр operator + ( Матр А, Матр В);

# include <iostream.h>

# include <stcllib.h>

class Circle

{float x, y;

int r;

public : Circle (float xx =1, float yy =1, int rad =1);

x (xx), y (yy), r (rad) { }

void print ( )

{cout <<”окружность с центром в т : “<<endl;

cout <<”x = ”<< x << ”y =” << y <<endl;

cout << ”radius = “<< r <<endl;

}

Circle operator + (Circle &);

int get_r ( ) {return r;} // член – функция get для доступа к полю r

int set_r ( int v ) {r = v;} // член – функция set для записи поля r

};

Circle :: Circle operator + (Circle & c)

{Circle vr;

vr. r = r + c.r; // vr. r = this → r + c.r

vr. x = x ; // vr. r = this →x

vr. y = y ; // vr. r = this →y

return vr;}

Circle operator_(Circle&C1, Circle&C2)

// перегрузка с помощью глобальной функции операции перегрузки “_”

abs ( )

{Circle c;

c. set_r (abc ( c1. get_r ( )_c2. get_r ( ) );

return c;

}

void main ( )

{Circle c1 (5, 5, 10 );

Circle c2 (3, 2, 7 );

Circle c;

c = c1. operator + c2

c. print ( );

c = operator_(с1, c2);

c. print ( );

}