Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Содержание сайт... 65535
Вызов хранимых ... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Invision Power ... 65263
Организация зап... 63916
Модуль Forms 60835
Создание отчето... 60694
ТЕХНОЛОГИИ ДОСТ... 57012
Создание потоко... 56345
Пример работы с... 54254
Имитационное мо... 52467
Реклама
Сейчас на сайте
Гостей: 12
На сайте нет зарегистрированных пользователей

Пользователей: 13,065
новичок: railval
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

Расчет обратной матрицы на Delphi + Пояснительная записка
База данных - словарь терминов на Delphi + Пояснительная записка
Метод конечных разностей для интерполяции/экстраполяции на Delphi

Реклама



Подписывайся на YouTube канал о программировании, что бы не пропустить новые видео!

ПОДПИСЫВАЙСЯ на канал о программировании
Проблема универсальности
Пока все хорошо и не видно никаких сложностей. Более того, наш стек «слишком» универсален — он может содержать элементы разного типа!
Однако не все так прекрасно, как представляется. Во-первых, на указатели расходуется дополнительная память.
Во-вторых, класс-стек понятия не имеет о реальном типе элементов в контейнере, поэтому не может выдать значение элемента, а вынужден выдавать указатель void *. Дальнейшее разыменование должна делать программа-клиент, обеспечивая еще и преобразование в нужный тип. При этом, конечно, приходится писать не самые красивые выражения.
Но гораздо более важным является то, что программа-клиент теперь обязана следить за памятью, ведь в контейнер помещается только указатель на некоторые данные. Этими данными владеет программа-клиент, и только она «знает», как с ними оперировать. И тут, как обычно это бывает при использовании указателей, может возникнуть множество проблем. Например, в стек вполне можно поместить адрес локальной переменной. Если стек имеет большее время жизни, чем эта переменная, то мы получим висячую ссылку. При использовании такого стека очень просто получить и потерянные ссылки. Если программа-клиент «забудет» освободить память, то при уничтожении стека-переменной (например, при выходе из блока) мы получим утечку памяти. Одним из решений проблем с указателями могут стать интеллектуальные указатели, которые в этой книге не рассматриваются1.
Дек (см. листинги 6.1, 6.2, 6.3) реализован для элементов типа double. Однако по сути дек тоже является универсальным контейнером, работа которого не зависит от типа элементов. К сожалению, использование указателей типа void * приведет к тем же проблемам, что и со стеком. Более того, поскольку в классе TDeque реализован деструктор, существует очень большая опасность получения утечек памяти. Поэтому применение нетипизированных указателей для универсализации дека не является самым лучшим решением.
Таким образом, мы видим, что написать универсальный контейнер, работа которого не зависит от типа элементов, не так-то просто. В С++ есть несколько вариантов решения этой проблемы. Одним из вариантов является наследование (см. главы 8 и 9), другим — шаблоны, включенные в С++ специально для решения такого рода проблем (см. главу 11).
Однако есть один очень простой, но очень полезный прием, который повышает степень универсальности динамических структур данных и позволяет повторно использовать уже разработанные классы с другим типом данных. Если еще раз взглянуть на класс TDeque (см. листинг 6.3), то ни в одном из компонентов класса мы не обнаружим спецификатор типа double. Поэтому явную зависимость класса TDeque от элементов типа double можно уменьшить, использовав оператор typedef:
Описание интеллектуальных указателей можно найти в [20, 25, 26, 28].
typedef double value_type:




После этого компоненты класса, явно зависящие от double, переписываются с типом value_type, например:
// в классе iterator
value_type& operator*() const
{ if (the_elem != 0) return the_elem->itern;
else { cout << "Null iterator!" << endl: abort(); }
}
// в классе TDeque - добавить элемент
void TDeque::push_front(const value_type &a)
{ Elem *p = new Elem(a); // образовали новый элемент
p->next = Head; p->prev = 0; // "привязали"
Head->prev = p; Head = p; // первым в деке
head = iterator(Head); // корректируем итератор
++count; // добавили элемент
}



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

Листинг 6.10. Динамический массив
class ТАггау
{ public:
// определение типов
typedef std::size_t size_type;
typedef std::size_t index_type;
typedef double value_type;
typedef double & reference;
typedef double * iterator;
typedef double * pointer;
TArray(size_type size, value_type k=0.0);
TArray(const TArray &a);
TArray(const TArray &a, index_type begin, size_type k);
TArray(const iterator begin, const iterator end);
-TArrayO ; reference operator[](index_type index); const reference operator[](index_type index) const; TArray& operator=(const TArray &a);
TArray& assign(const TArray &a, index_type I, index_type r); TArray& assign(const iterator begin, const iterator end); size_type size()const { return size_array; }; iterator find(const value_type &a); friend ostream& operator <<(ostream& to, const TArray &a); friend istream& operator >>(istream& to, TArray &a); private:
size_type size_array; pointer data;
>:



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

Резюме
Поскольку встроенных массивов явно не хватает для обработки групп однотипных данных, программистское сообщество предложило более общую конструкцию объединения однородных данных в группу — контейнер. Все контейнеры обладают некоторыми свойствами. Одним из важнейших характеристик контейнера является способ доступа к элементам: последовательный, прямой или ассоциативный.
Прямой и ассоциативный варианты доступа обычно реализуются посредством перегрузки операции индексирования operator!], а последовательный — реализацией класса-итератора. Такая реализация имеет еще и то преимущество, что отделяет интерфейс доступа от интерфейса контейнера. Так как итератор тесно связан с внутренней структурой контейнера, его обычно создают как вложенный класс.
Для контейнеров реализуется множество операций, однако одна из наиболее часто используемых — операция объединения контейнеров, реализуемая самыми разнообразными способами.
Динамические структуры данных, как правило, являются универсальными структурами, работа которых не зависит от типа элемента. Таковыми являются стек, очередь и дек, которые различаются только дисциплиной добавления и удаления элементов. Как правило, такие структуры реализуются с помощью связанных списков. Однако написать универсальный класс без использования механизма наследования или шаблонов достаточно сложно — как правило, приходится задействовать нетипизированные указатели, которые потенциально опасны.
Опубликовал Kest November 07 2013 17:36:58 · 0 Комментариев · 1752 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Комментарии
Нет комментариев.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
База англоязычных...
Delphi 2005. Разр...
Разработка клиент...
Размещение элемен...
C++ Builder: Книг...
Пример работы с р...
Ранги для форума
Простой пример ка...
PHP, MySQL и Drea...
Программа для рис...
ИНТЕРНЕТ ПРОГРАММ...
Панель Календарь
Strawberry Prolog...
Dbgridpack
CoolDev TipsSyste...
Разработка интерн...
Report
Trojan [Исходник ...
PHP: Полезные приемы
MP3 Архив v.2.0

Топ загрузок
Приложение Клие... 100376
Delphi 7 Enterp... 83066
Converter AMR<-... 20046
Borland C++Buil... 11173
GPSS World Stud... 10888
Borland Delphi ... 8120
Turbo Pascal fo... 6973
Visual Studio 2... 4963
Калькулятор [Ис... 4355
FreeSMS v1.3.1 3510
Случайные статьи
Списки из неодноро...
File: are not allo...
Решения к главе 10
Блок MARK
Описание GPSS-прог...
2.1. Синтаксическ...
Генерирование сигн...
Invalid relocatabl...
Основные комбинаторы
чтения смарт-карт,...
Сохранение «образа...
Настройка дизайн-т...
ЭТАП 4. ПРИМЕР РЕА...
Работа с MySql...
Операторы ввода-вы...
Игры для взрослых
Анонимный доступ г...
Лист рабочей книги...
Детская одежда
Макросы в языке С
Аналоговые и цифро...
Процедура MoveTo -...
Описание управляем...
Новый корпус для ЭЛТ
2.1. ЦЕЛЬ: ХРАНЕНИ...
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?