Читаем C++ полностью

Дается три функции: iterate() для инициализации итерции, ok() для проверки, есть ли следующий элемент, и next() для того, чтобы взять следующий элемент:

class intset (* // ... void iterate(int amp; i) (* i = 0; *) int ok(int amp; i) (* return i«cursize; *) int next(int amp; i) (* return x[i++]; *) *);

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

void print_in_order(intset* set) (* int var; set-»iterate(var); while (set-»ok(var)) cout «„ set-“next(var) „« «\n“; *)

Другой способ задать итератор приводится в #6.8.

<p>5.4 Друзья и Объединения</p>

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

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.

<p>5.4.2 Уточнение* Имени Члена</p>

– * Иногда называется также квалификацией. (прим. перев.)

Иногда полезно делать явное различие между именами члнов класса и прочими именами. Для этого используется операция ::, «разрешения области видимости»:

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных