1.15 Друзья (friend)

1.15 Друзья (friend)

Функция operator+() не воздействует непосредственно на представление вектора. Действительно, она не может этого делать, поскольку не является членом. Однако иногда желательно дать функциям не членам возможность доступа к закрытой части класса. Например, если бы не было функции «доступа без проверки» vector::elem(), вам пришлось бы проверять индекс i на соответствие границам три раза за каждый проход цикла. Здесь мы избежали этой сложности, но она довольно типична, поэтому у класса есть механизм предоставления права доступа к своей закрытой части функциям не членам. Просто в класс помещается описание функции, перед которым стоит ключевое слово friend. Например, если имеется

class Vec; // Vec – имя класса class vector (* friend Vec operator+(Vec, Vec); //... *);

То вы можете написать Vec operator+(Vec a, Vec b) (* int s = a.size(); if (s != b.size()) error(«bad vector size for +»); // плохой размер вектора для + Vec amp; sum = *new Vec(s); int* sp = sum.v; int* ap = a.v; int* bp = b.v; while (s–) *sp++ = *ap++ + *bp++; return sum; *)

Одним из особенно полезных аспектов механизма friend является то, что функция может быть другом двух и более классов. Чтобы увидеть это, рассмотрим определение vector и matrix, а затем определение функции умножения (см. #с.8.8).

1.16 Обобщенные Вектора

«Пока все хорошо,» – можете сказать вы, – «но я хочу, чтобы один из этих векторов был типа matrix, который я только что определил.» К сожалению, в С++ не предусмотрены средства для определения класса векторов с типом элемента в качестве параметра. Один из способов – продублировать описание и класса, и его функций членов. Это не идеальный способ, но зачатую вполне приемлемый.

Вы можете воспользоваться препроцессором (#4.7), чтобы механизировать работу. Например, класс vector – упрощенный вариант класса, который можно найти в стандартном заголовочном файле. Вы могли бы написать:

#include «vector.h»

declare(vector,int);

main() (* vector(int) vv(10); vv[2] = 3; vv[10] = 4; // ошибка: выход за границы *)

Файл vector.h таким образом определяет макросы, чтобы макрос declare(vector,int) после расширения превращался в описание класса vector, очень похожий на тот, который был определен выше, а макрос implement(vector,int) расширялся в определение функций этого класса. Поскольку макрос implement(vector,int) в результате расширения превращается в

определение функций, его можно использовать в программе только один раз, в то время как declare(vector,int) должно использоваться по одному разу в каждом файле, работающем с этим типом целых векторов.

declare(vector,char); //... implement(vector,char);

даст вам отдельный тип «вектор символов». Пример реализации обобщенных классов с помощью макросов приведен в #7.3.5.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг:

Совет 21: Опасные друзья

Из книги автора

Совет 21: Опасные друзья Если взрослый способен сам оградить себя от не очень умных людей из интер нета, то ребенок, увы, может быть не очень разборчивым. Общение с неизвестными пользователями может быть не просто неприятным, а очень опасным, ведь ребенку неоткуда знать, что


Кандинский и Воннегут теперь друзья

Из книги автора

Кандинский и Воннегут теперь друзья Зная, как легко в Сети формируются группы, просто ошибиться, приняв количество за качество. “Фейсбук” уже способствует процессам, которые не требуют социальных скреп. Истина в том, что людям свойственно собираться в группы. Социальным


Френды (друзья) в блогах. Образование сообществ

Из книги автора

Френды (друзья) в блогах. Образование сообществ Как уже неоднократно было сказано, особенность Web 2.0 – его интерактивность. Создатели концепции Web 2.0 считают, что только сами люди могут определить, что на самом деле им надо, и самостоятельное решение этого вопроса –


Френды (друзья) в блогах

Из книги автора

Френды (друзья) в блогах Как уже неоднократно обсуждалось, особенность современной части Интернета, которую называют Web 2.0 – его интерактивность. Создатели концепции Web 2.0 считают, что только сами люди могут определить, что на самом деле им надо, и самостоятельное решение


Друзья

Из книги автора

Друзья Искать друзей ВКонтакте не так уж сложно, ибо сделать это можно как целой кучей способов. Самый простой из них – найти страничку интересного тебе человека и щелкнуть по кнопке  – как, в общем-то, большинство и делает. Правда, надо еще дождаться, чтобы выбранный


Зачем компании нужны друзья на Facebook?

Из книги автора

Зачем компании нужны друзья на Facebook? Если вы знаете ответ на данный вопрос, то можете пропустить эту главу. Если сомневаетесь в ответе, давайте порассуждаем вместе. Я знаю как минимум пять причин:1. Поддержание отношений с имеющимися клиентами.2. Поиск новых клиентов через


Генераторы - лучшие друзья первичных ключей

Из книги автора

Генераторы - лучшие друзья первичных ключей Надо сказать несколько слов о реализации первичного ключа. Так как он предназначен для обеспечения уникальности, то никакие две записи в одной таблице не могут иметь одинаковых значений этого ключа. То есть, чтобы


R.7.1.5 Спецификация friend

Из книги автора

R.7.1.5 Спецификация friend Спецификация friend используется для задания доступа к членам класса (см.


R.11.4 Друзья

Из книги автора

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


R.14.7 Друзья

Из книги автора

R.14.7 Друзья Функция-друг для шаблона типа не является неявной шаблонной функцией, например:template‹class T› class task { //… friend void next_time(); friend task‹T›* preempt(task‹T›*); friend task* prmt(task*); // ошибка //…};Здесь функция next_time() становится другом всех классов task, а каждый класс task имеет в качестве


13.1.4. Друзья

Из книги автора

13.1.4. Друзья Иногда удобно разрешить некоторым функциям доступ к закрытым членам класса. Механизм друзей позволяет классу разрешать доступ к своим неоткрытым членам.Объявление друга начинается с ключевого слова friend и может встречаться только внутри определения класса.


13. 15.2. Друзья

Из книги автора

13. 15.2. Друзья Рассмотрим еще раз перегруженные операторы равенства для класса String, определенные в области видимости пространства имен. Оператор равенства для двух объектов String выглядит следующим образом:bool operator==( const String &str1, const String &str2 ){if ( str1.size() != str2.size() )return false;return


5.4 Друзья и Объединения

Из книги автора

5.4 Друзья и Объединения В это разделе описываются еще некоторые особенности, ксающиеся классов. Показано, как предоставить функции не члену доступ к закрытым членам. Описывается, как разрешать конфлиты имен членов, как можно делать вложенные описания классов, и как


5.4 Друзья и Объединения

Из книги автора

5.4 Друзья и Объединения В это разделе описываются еще некоторые особенности, ксающиеся классов. Показано, как предоставить функции не члену доступ к закрытым членам. Описывается, как разрешать конфликты имен членов, как можно делать вложенные описания классов, и как


5.4.1 Друзья

Из книги автора

5.4.1 Друзья Предположим, вы определили два класса, vector и matrix (вектор и матрица). Каждый скрывает свое представление и прдоставляет полный набор действий для манипуляции объектами его типа. Теперь определим функцию, умножающую матрицу на вектор. Для простоты допустим, что в


6.10 Друзья и Члены

Из книги автора

6.10 Друзья и Члены Теперь, наконец, можно обсудить, в каких случаях для доступа к закрытой части определяемого пользователем типа ипользовать члены, а в каких – друзей. Некоторые операции должны быть членами: конструкторы, деструкторы и виртуальные функции (см. следующую