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

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

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

Рассмотрим простой класс X:

class X (* // ... X(int); int m(); friend int f(X amp;); *);

Внешне не видно никаких причин делать f(X amp;) другом дполнительно к члену X::m() (или наоборот), чтобы реализовать действия над классом X. Однако член X::m() можно вызывать только для «настоящего объекта», в то время как друг f() мжет вызываться для объекта, созданного с помощью неявного преобразования типа. Например:

void g() (* 1.m(); // ошибка f(1); // f(x(1)); *)

Поэтому операция, изменяющая состояние объекта, должна быть членом, а не другом. Для определяемых пользователем тпов операции, требующие в случае фундаментальных типов опранд lvalue (=, *=, ++, *= и т.д.), наиболее естественно оределяются как члены.

И наоборот, если нужно иметь неявное преобразование для всех операндов операции, то реализующая ее функция должна быть другом, а не членом. Это часто имеет место для функций, которые реализуют операции, не требующие при применении к фундаментальным типам lvalue в качестве операндов (+, -, !! и т.д.).

Если никакие преобразования типа не определены, то окзывается, что нет никаких существенных оснований в пользу члена, если есть друг, который получает ссылочный параметр, и наоборот. В некоторых случаях программист может предпочитать один синтаксис вызова другому. Например, оказывается, что большинство предпочитает для обращения матрицы m запись m.inv (). Конечно, если inv() действительно обращает матрицу m, а не просто возвращает новую матрицу, обратную m, ей следует быть членом.

При прочих равных условиях выбирайте, чтобы функция была членом: никто не знает, вдруг когда-нибудь кто-то определит операцию преобразования. Невозможно предсказать, потребуют ли будущие изменения изменять состояние объекта. Синтаксис вызва функции члена ясно указывает пользователю, что объект моно изменить; ссылочный параметр является далеко не столь очвидным. Кроме того, выражения в члене могут быть заметно короче выражений в друге. В функции друге надо использовать явный параметр, тогда как в члене можно использовать неявный this. Если только не применяется перегрузка, имена членов

обычно короче имен друзей.

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

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

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

Совет 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 и может встречаться только внутри определения класса.


15.1.1. Члены и не члены класса

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

15.1.1. Члены и не члены класса Рассмотрим операторы равенства в нашем классе String более внимательно. Первый оператор позволяет устанавливать равенство двух объектов, а второй – объекта и C-строки:#include "String.h"int main() {String flower;// что-нибудь записать в переменную flowerif ( flower == "lily" ) //


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 Друзья и Объединения

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

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


5.4.1 Друзья

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

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