|
Программирование >> Расширенная версия языка c++
.Замечание В предыдущее еле был рассмотрен важные ент. Когда функция-член использует закрытый элемент класса, то это делается непосредственно, поскольку функция-член выполняется только с объектами данного класса. Таким образом, если в функции-члене класса упоминается закрытый элемент этого класса, то компилятор знает, к какому объекту этот закрытый элемент относится, поскольку знает, с каким объектом при 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 ;
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |