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

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

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

5.4.1 Друзья

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

vector multiply(matrix amp; m, vector amp; v); (* vector r; for (int i = 0; i«3; i++) (* // r[i] = m[i] * v; r.elem(i) = 0; for (int j = 0; j«3; j++) r.elem(i) += m.elem(i,j) * v.elem(j); *) return r; *)

Это своего рода «естественный» способ, но он очень неэфективен. При каждом обращении к multiply() elem() будет взываться 4*(1+4*3) раза.

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

class matrix;

class vector (* float v[4]; // ... friend vector multiply(matrix amp;, vector amp;); *);

class matrix (* vector v[4]; // ... friend vector multiply(matrix amp;, vector amp;); *);

Функция друг не имеет никаких особенностей, помимо права доступа к закрытой части класса. В частности, friend функция не имеет указателя this (если только она не является полноравным членом функцией). Описание friend – настоящее описние. Оно вводит имя функции в самой внешней области видимости программы и сопоставляется с другими описаниями этого имени. Описание друга может располагаться или в закрытой, или в отрытой части описания класса. Где именно, значения не имеет.

Теперь можно написать функцию умножения, которая исползует элементы векторов и матрицы непосредственно:

vector multiply(matrix amp; m, vector amp; v); (* vector r; for (int i = 0; i«3; i++) (* // r[i] = m[i] * v; r.v[i] = 0;

for (int j = 0; j«3; j++) r.v[i] += m.v[i][j] * v.v[j]; *) return r; *)

Есть способы преодолеть эту конкретную проблему эффетивности не используя аппарат friend (можно было бы определить операцию векторного умножения и определить multiply() с ее помощью). Однако существует много задач, кторые проще всего решаются, если есть возможность предоствить доступ к закрытой части класса функции, которая не явлется членом этого класса. В Главе 6 есть много примеров применения friend. Достоинства функций друзей и членов будут обсуждаться позже.

Функция член одного класса может быть другом другого. Например:

class x (* // ... void f(); *);

class y (* // ... friend void x::f(); *);

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

class x (* friend class y; // ... *);

Такое описание friend делает все функции члены класса y друзьями x.

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

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

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

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

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

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


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

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

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


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

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

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


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

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

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


Друзья

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

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


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

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

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


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

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

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


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


1.15 Друзья (friend)

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

1.15 Друзья (friend) Функция operator+() не воздействует непосредственно на представление вектора. Действительно, она не может этого делать, поскольку не является членом. Однако иногда желательно дать функциям не членам возможность доступа к закрытой части класса. Например, если


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

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

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


5.4.1 Друзья

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

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


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

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

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