5.3.1 Альтернативные реализации.

   


Назад  |  Вперёд

Пока описание общей части класса и функций-членов остается неизменным, можно, не влияя на пользователей класса, менять его реализацию. В подтверждение этого рассмотрим таблицу имен из программы калькулятора, приведенной в главе 3. Структура ее такова:

           struct name {
             char* string;
             name* next;
             double value;
           };

А вот вариант класса table (таблица имен):

           // файл table.h
           class table {
              name* tbl;
           public:
              table() { tbl = 0; }

              name* look(char*, int = 0);
              name* insert(char* s) { return look(s,1); }
           };

Эта таблица отличается от определенной в главе 3 тем, что это настоящий тип. Можно описать несколько таблиц, завести указатель на таблицу и т.д. Например:

           #include "table.h"

           table globals;
           table keywords;
           table* locals;

           main()
           {
             locals = new table;
             // ...
           }

Приведем реализацию функции table::look(), в которой используется линейный поиск в списке имен таблицы:

           #include <string.h>

           name* table::look(char* p, int ins)
           {
             for (name* n = tbl; n; n=n->next)
                 if (strcmp(p,n->string) == 0) return n;
             if (ins == 0) error("имя не найдено");

             name* nn = new name;
             nn->string = new char[strlen(p)+1];
             strcpy(nn->string,p);
             nn->value = 1;
             nn->next = tbl;
             tbl = nn;
             return nn;
           }

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

           class table {
              name** tbl;
              int size;
           public:
              table(int sz = 15);
              ~table();

              name* look(char*, int = 0);
              name* insert(char* s) { return look(s,1); }
           };

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

           table::table(int sz)
           {
             if (sz < 0) error("размер таблицы отрицателен");
             tbl = new name*[size = sz];
             for ( int i = 0; i<sz; i++) tbl[i] = 0;
           }

           table::~table()
           {
             for (int i = 0; i<size; i++) {
                 name* nx;
                 for (name* n = tbl[i]; n; n=nx) {
                     nx = n->next;
                     delete n->string;
                     delete n;
                 }
             }
             delete tbl;
           }

Описав деструктор для класса name, можно получить более ясный и простой вариант table::~table(). Функция поиска практически совпадает с приведенной в примере калькулятора ($$3.13):

           name* table::look(const char* p, int ins)
           {
             int ii = 0;
             char* pp = p;
             while (*pp) ii = ii<<1 ^ *pp++;
             if (ii < 0) ii = -ii;
             ii %= size;

             for (name* n=tbl[ii]; n; n=n->next)
                 if (strcmp(p,n->string) == 0) return n;

              name* nn = new name;
              nn->string = new char[strlen(p)+1];
              strcpy(nn->string,p);
              nn->value = 1;
              nn->next = tbl[ii];
              tbl[ii] = nn;
              return nn;
           }

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

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

Можно не знать определения всего класса, если представлять каждый объект как указатель на "настоящий" объект. Это позволяет решить задачу, поскольку все указатели будут иметь одинаковый размер, а размещение настоящих объектов будет проводиться только в одном файле, в котором доступны частные части классов. Однако, такое решение приводит к дополнительному расходу памяти на каждый объект и дополнительному обращению к памяти при каждом использовании члена. Еще хуже, что каждый вызов функции с автоматическим объектом класса требует вызовов функций выделения и освобождения памяти. К тому же становится невозможной реализация подстановкой функций-членов, работающих с частными членами класса. Наконец, такое изменение сделает невозможным связывание программ на С++ и на С, поскольку транслятор С будет по другому обрабатывать структуры (struct). Поэтому такое решение было сочтено неприемлемым для С++.

С другой стороны, С++ предоставляет средство для создания абстрактных типов, в которых связь между интерфейсом пользователя и реализацией довольно слабая. В главе 6 вводятся производные классы и описываются абстрактные базовые классы, а в $$13.3 поясняется, как с помощью этих средств реализовать абстрактные типы. Цель этого - дать возможность определять пользовательские типы столь же эффективные и конкретные, как и стандартные, и дать основные средства определения более гибких вариантов типов, которые могут оказаться и не столь эффективными.


Назад  |  Вперёд


OtDiatlovaOU
К началу книги

Оформление и дизайн книги OtDiatlovaOU.
Вся книга, архив.

Программирование, блок схема, программа, информатика, алгоритм, управление, система управления, разделяй властвуй, языки программирования, линейное программирование, сложность, книги программирование, организация, развитие, проектирование, самосовершенствование, развитие систем, программирование скачать, программирование c, задачи программирование, динамическое программирование, ориентированное программирование, методы программирования, объектно программирование, примеры программирования, задача линейного программирования, основы программирования, объектно ориентированное программирование, программирование учебник, технология программирования, программирование си, программирование скачать книги, исходники, исходники на c, c, с, програмирование, книги по с, разработка программ, государственное управление, методы управления, управление организацией, структуры управления, управление проектами, управление рисками, теории управления, скачать управление, процесс управления, исследование управления, программа управления, схемы управления, информационное управление, управление образования, стратегическое управление, исследование систем управления, социальное управление, функции управления, технология управления, модели управления, блок управления, организационное управление, менеджмент управления, психология управления, управление ресурсами, управление производством, принципы управления, корпоративное управление, управление работами, дистанционное управление, эффективность управления, управление компьютером, пульты управления, проблемы управления, области управления, основы управления, управление конфликтами, обеспечение управления, управление деятельностью, анализ управления, автоматизированное управление, стили управления, организационные структуры управления, автоматическое управление, современное управление, подходы управления, управление службами, стратегии управления, социология управления, управление развитием, объект управления, информационные технологии управления, автоматизированные системы управления, совершенствование управления, управление средствами, управление потоками, оперативное управление, механизм управления, управление удаленным, примеры управления, управление через, понятие управление, особенности управления, задачи управления, сфера управления, управление культуры, право управления, управление собственностью, управление книги, концепция управления, управление трудом, панель управления, опыт управления, информационные системы управления, формы управления, роль управления, политика управления, контроль управления, организация, управление организацией, организация труда, организация производства, теория организации, организация система, организация учета, структура организации, формы организации, анализ организации, принципы организации, организация процессов, развитие организации, пример организации , среда организации, организация контроля, метод организации, внутренняя организация, стратегии организации, понятие организация, уровни организации, основы организации, функции организации, современная организация, организация проекта, развитие, перспективы развития, этапы развития, программа развития, тенденции развития, развитие систем, стратегия развития, проблемы развития, концепция развития, развитие личности, дети развитие, современное развитие, развитие ребенка, план развития, теория развития, психология развития, особенности развития, развитие техники, развитие человека, развитие образования, устойчивое развитие, развитие памяти, фактор развития, развитие способностей, управление развитием, развитие связи, развитие технологии, развитие мышления, направления развития, пути развития, модели развития, русское развитие, развитие жизни, основные этапы развития, развитие страны, возникновение развитие, стратегическое развитие, развитие информационного развития, скачать развитие, развитие персонала, методы развития, творческое развитие, развитие языка, развитие школьника, проектирование, проектирование систем, проектирование программа, нормы проектирования, проектирование информационных, проектирование данных, проектирование информационной системы, проектирование базы, организационное проектирование, основы проектирования, автоматизированное проектирование, проектирование скачать, организация проектирования, методы проектирования, управление проектирование, технологическое проектирование, проектирование процессов, этапы проектирования, системы автоматизированного проектирования

Rambler's Top100
Hosted by uCoz