Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Шпоры / ООП(Тимофеев) / ООП-Тимофеев.doc
Скачиваний:
41
Добавлен:
16.04.2013
Размер:
328.19 Кб
Скачать

Пример: динамически размещаемые строки

Языку C++ недостает собственного строкового типа. Стандартная библиотека предоставляет шаблонный строковый класс — тип, который используется все чаще и чаще. Старое строковое представление выглядело как указатель на char. В этом представлении конец строки обозначался нулевым символом ' \0 '.

В этом разделе мы разработаем полезныи строковый АТД, в котором длина объявлена как private.

Реализация будет использовать строковые функции из библиотеки string.h для оперирования вышеупомянутым представлением строк с помощью указателей.

………Этот тип позволяет объявлять строки my_string, присваивать с помощью копирования одну my_string другой, печатать строки и объединять две строки типа my_string. Скрытое представление является указателем на char и содержит переменную len, в которой хранится текущая длина строки типа my_string.

Следующая программа тестирует класс my_string, выполняя конкатенацию нескольких строк типа my_string.

Пример: односвязный список

Разработаем тип данных для односвязного списка. Он является прототипом для многих динамических АТД, которые называются ссылающимися на себя структурами (self-referential structure). Такие типы данных содержат члены-указатели, которые ссылаются на объекты своего собственного типа. Они служат основой для многих полезных контейнерных классов.

Операции над списком

1. prepend: добавляет в голову списка 2. first: возвращает указатель на первый элемент 3. print: печатает содержимое списка 4. del: удаляет первый элемент

5. release: уничтожает список

Связующий член next указывает на следующий slistelem в списке. Переменная data в этом примере является простой переменной, но она может быть заменена на сложный тип, способный хранить целую порцию информации. Конструктор инициализует голову списка slist (указатель h ) значением 0, которое называется постоянной нулевого указателя (null pointer constant) и может быть присвоено указателю любого типа. В связных списках она обычно обозначает пустой список или значение «конец списка». Функция-член prepend () строит структуру списка:

void slist::prepend(char с)

{

slistelem* temp = new slistelem; //создание элемента

assert(temp != 0);

temp -> next = h; //связь с slist

temp -> data = c;

h = temp; //изменение головы списка

}

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

Строки, использующие семантику ссылок

В следующем примере мы создадим класс my_string, имеющий ссылочную семантику копирования. Этот класс использует поверхностное копирование, поскольку копирование заменено присваиванием указателей. Показанная техника обычна для агрегатов данных подобного типа. Будем использовать класс str_obj для создания значений фактических объектов. Тип str_obj является необходимой деталью реализации my_string. Данная деталь не может быть помещена непосредственно в my_string без разрушения отношения (возможно, многие-к-одному) между объектами типа my_string и ссылочными значениями типа str_obj. Значения my_string содержатся в str_obj, который является дополнительным классом только лишь для использования классом my_string. Открыто используемый класс my_string управляет экземплярами str_obj, и иногда называется управляющим классом (handler class).

//Строки my_string с подсчетом ссылок

#include <string.h> #include <iostream.h> #include <assert.h>

class str_obj {

public: int len, ref_cnt; char* s;

str_obj() : len(0), ref_cnt(l)

{ s = new char[l]; assert(s != 0); s[0] = 0; }

str_obj(const char* p) : ref_cnt(l)

{ len = strlen(p); s = new char[len + 1] ;

assert(s != 0); strcpy(s, p); }

~str_obj() { delete []s; } };

Класс str_obj объявляет объекты, которые используются my_string. Обратите внимание, что класс str_obj применяется в основном для создания и уничтожения объектов, использующих свободную память. При создании str_obj переменная ref_cnt инициализуется единицей.

…….. Каждый| раз, когда счетчик ссылок объекта уменьшается, он проверяется на предмет удаления.

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

Для хранения счетчика ссылок требуется небольшое количество дополнительной памяти. Кроме того, каждое возможное изменение указателя влечет операцию со счетчиком ссылок. Деструктор также должен проверять счетчик ссылок перед фактическим удалением. my_string:: ~ my_string ()

{ if (--st -> ref_cnt = =0) delete st; }

Соседние файлы в папке ООП(Тимофеев)