Программирование >>  Расширенная версия языка c++ 

1 ... 28 29 30 [ 31 ] 32 33 34 ... 227


.Замечание

В предыдущее еле был рассмотрен важные ент. Когда функция-член использует закрытый элемент класса, то это делается непосредственно, поскольку функция-член выполняется только с объектами данного класса. Таким образом, если в функции-члене класса упоминается закрытый элемент этого класса, то компилятор знает, к какому объекту этот закрытый элемент относится, поскольку знает, с каким объектом при Phimnc функции-члена связана функция. Однако дружественная функция не связана с каким бы то ни было объектом. Просто ей предоставлен доступ к закрытым элементам класса. Поэтому дружественная функция не может работать с закрытыми членами класса без упоминания конкретного объекта.

Поскольку дружественные функции - это не члены класса, им обычно передается один или более объектов класса, для которого они являются дружественными. Так было сделано, например, в случае с функцией tor() Ей был передан объект ob класса myclass. Поскольку функция isfactor() дружественна для класса myclass, она может иметь доступ к закрытым элементам этого класса через объект ob. Случись так, что функция isfactorQ не была бы дружественной для класса myclass, она не имела бы доступа ни к объекту оЬ.п, ни к объекту ob.d, поскольку переменные п и d - это закрытые члены класса myclass.


Дружественная функция - это не член класса и она не может быть задана через имя объекта. Она должна вызываться точно так же, как и обычная функция.

Дружественная функция не наследуется. Поэтому если в базовый класс включается дружественная функция, то эта дружественная функция не является таковой для производных классов.

Другим важным моментом, относящимся к дружественным функциям, является то, что функция может быть дружественной более чем к одному классу.

На самом деле дружественная функция должна вызываться точно так же,

как и обычная функция.

Хотя дружественная функция знает о закрытых элементах класса, для которого она является дружественной, доступ к ним она может получить только через объект этого класса. Таким образом, в отличие от функции-члена myclass, в котором можно непосредственно упоминать переменные п и d, дружественная функция может иметь доступ к этим переменным только через объект, который объявлен внутри функции или передан ей.




1. Обычно дружественная функция бывает полезна да, когда у двух разных классов имеется нечто общее, что необходимо сравнить. Например, рассмотрим следующую программу, в которой создаются классы саг (легковая машина) и truck (грузовик), причем оба содержат в закрытой переменной скорость соответствующего транспортного средства:

ttinclude <iQstream>

using namespace

class truck; предварительное объявление

class car {

int passengers;

int speed; ...

public: . . - ...

car(int p, int s) { passengers speed }

friend int sp greater (car c, truck t) ;

class truck { -

int weight; int speed;

public:

truck(int w, int s) { weighs w; speed = s; ; friend int sp greater (car c, truck t) ;

Возвращает положительное число, если легковая машина быстрее грузовика. Возвращает 0 при одинаковых скоростях. Возвращает отрицательное число, если грузовик быстрее овой машины. * /

in ter (car c, truck t) ...

return peed - t. speed;

int t;

car cl(6, 5) , c2 (2, 120) ;

truck ti (10000, 55), t2(2000Q, 72);

cou Сравнение значение cl и tl:\n ;

t = tl);

if(t<0) cou Грузовик быстрее. \n ;

els =0) cou Скорости машин одинаковы. \n ;

else cou << Легковая машина быстрее. \n ;



return 0;

В этой программе имеется функции ater(), которая дружественна для классов саг и truck. (Как уже установлено, функция может быть дружественной двум и более классам.) Эта функция возвращает положительное число, если объект саг движется быстрее объекта truck, нуль, если их скорости одинаковы, и отрицательное число, если скорость объекта truck больше, чем скорость объекта саг.

Эта программа иллюстрирует один важный элемент синтаксиса C++ - предварительное объявление (forward declaration), которое еще называют ссылкой вперед (forward reference). Поскольку функция sp greater() получает параметры обоих классов саг и truck, то логически невозможно объявить и тот и другой класс перед включением функции sp greater() в каждый из них. Поэтому необходим иной способ сообщить компилятору имя класса без его фактического объявления. Эгот способ и называется предварительным объявлением. В < i . чтобы информировать компилятор о том, что данный идентификатор является именем класса, перед первым использованием имени класса вставляют следующую строку:

class имя класса г

имср, в предыдущей программе предварительным объявлением является инструкция

class truck;

после которой класс track можно использовать в объявлении дружественной функции sp greater() без опасения вызвать ошибку компилятора.

2. Функция может быть членом одного класса и дружественной другому. Например, если переписать предыдущий пример так, чтобы функция sp greater() являлась членом класса саг и дружественной классу track, то получится следующая программа:

ftinclude--o-:st-reain> ... .

using namespace ,std; .

class truck; предварительное объявление

class car {

int passengers; int speed;

cou равыение значений с2 и t2:\n ;

t = sp greatertc2, t2) ; - :

if{t<0) cout Грузовик быстрее.

else if(t==0) cout Скорости машин одинаковы. \n ; else cout Легковая машина быстрее. \n ;



1 ... 28 29 30 [ 31 ] 32 33 34 ... 227

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика