[ <<< | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Источники | >>> ]


© 2001 А.И. Легалов

Процедурное агрегирование

Построение агрегатов при процедурном подходе осуществляется с использованием следующих понятий:

Процедура используют запись в качестве элемента списка параметров, обеспечивая тем самым связь с различными экземплярами и их обработку. Элементы записи, в свою очередь, могут относиться как к базовым данным, так и иметь более сложную организацию, то есть быть агрегатами или обобщениями. Обработка записей независимыми процедурами осуществляется после передачи входных параметров через сигнатуру в тело процедуры. Тело независимой процедуры представляет агрегат, в котором запись расщепляется на отдельные элементы, каждый из которых обрабатывается своей независимой процедурой.

Пример использования процедурного агрегирования

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

//--------------------------------------------------------
// Простейший контейнер на основе одномерного массива
//--------------------------------------------------------
// Контейнер должен знать о фигуре
#include "shape_atd.h" 
//--------------------------------------------------------
// Данные контейнера
struct container
{
    enum {max_len = 100}; // максимальная длина
    int len; // текущая длина
    shape *cont[max_len];
};
//--------------------------------------------------------

В контейнере хранятся различные геометрические фигуры, определяемые обобщением shape, которое должно быть предварительно определено. Внутренняя организация АТД shape роли не играет, так как она доступна через сигнатуры функций, обрабатывающих обобщение. Этот прием демонстрирует возможность сокрытия данных от пользователя и в процедурном подходе. К независимым процедурам, осуществляющим полную обработку элементов представленного агрегата данных, можно отнести:

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

//--------------------------------------------------------------------
// Процедуры должны знать о контейнере и фигуре,
// доступной через модуль, описывающий контейнер
#include "container_atd.h"
//--------------------------------------------------------------------
// Инициализация контейнера
void Init(container &c) 
{
    c.len = 0;
}
//--------------------------------------------------------------------
// Очистка контейнера от элементов (освобождение памяти)
void Clear(container &c)
{
    for(int i = 0; i < c.len; i++)
    {
      delete c.cont[i];
    }
    c.len = 0;
}
//--------------------------------------------------------------------
// Необходим прототип функции, формирующей фигуру при вводе
shape *In();
//--------------------------------------------------------------------
// Ввод содержимого контейнера
void In(container &c) {
    cout 
      << "Do you want to input next shape"
         " (yes=\'y\', no=other character)? " 
      << endl;
    char k;
    cin >> k;
    while(k == 'y')
    {
      cout << c.len << ": ";
      if((c.cont[c.len] = In()) != 0)
      {
        c.len++;
      }
      cout 
        << "Do you want to input next shape"
           " (yes=\'y\', no=other character)? " 
        << endl;
      cin >> k;
    }
}
//--------------------------------------------------------------------
// Необходим прототип функции вывода отдельной фигуры 
void Out(shape &s);
//--------------------------------------------------------------------
// Вывод содержимого контейнера
void Out(container &c) 
{
    cout << "Container contents " << c.len << " elements." << endl;
    for(int i = 0; i < c.len; i++) 
    {
      cout << i << ": ";
      Out(*(c.cont[i]));
    }
}
//--------------------------------------------------------------------
// Необходим прототип функции, вычисляющей площадь отдельной фигуры 
double Area(shape &s);
//--------------------------------------------------------------------
// Вычисление суммарной площади для фигур, размещенных в контейнере
double Area(container &c) 
{
    double a = 0;
    for(int i = 0; i < c.len; i++) 
    {
      a += Area(*(c.cont[i]));
    }
    return a;
}
//--------------------------------------------------------------------

Указанные функции использованы в примере, расположенном в архиве pp_examp1.zip.


[ <<< | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Источники | >>> ]