С++ - язык, который изучается постепенно.Стеки образов
                   Справочники Всё для создания сайта

Ссылки


Home
Бизнес
Справочники
Советы







Материалы книги получены с http://www.itlibitum.ru/

Стеки образов

Для многоуровневой отмены вам может понадобиться стек предыдущих образов. Один из вариантов реализации - хранить стек в каждом указателе образов. В следующем фрагменте предполагается, что у вас имеется параметризованный класс Stack с функциями Empty(), Push(), Pop() и DeleteAll().

Функция Pop() возвращает верхний элемент стека или NULL, если стек пуст. Функция DeleteAll() опустошает стек и уничтожает все объекты по мере их извлечения. Каждый указатель хранит стек предыдущих образов. Если стек пуст, значит, образы не создавались. Если стек не пуст, в его нижней части находится исходный объект. Функция Rollback() находит и восстанавливает этот объект. Конструктор копий и оператор = работают так же, как и в описанном выше простейшем указателе образов.

template <class Type>

class ImageStackPtr {

private:

Type* current; // Текущий образ, предоставляемый клиенту

Stack<Type> history; // Предыдущие образы

public:

ImageStackPtr() : current(new Type) {}

ImageStackPtr(const ImageStackPtr<Type>& ip)

: current(new Type(*(ip.current))) {}

~ImageStackPtr() { delete current; }

ImageStackPtr<Type>& operator=(const ImageStackPtr<Type>& ip)

{

if (this != &ip) {

history.DeleteAll();

delete current;

current = new Type(*(ip.current));

}

return *this;

}

void PushImage()

{

history.Push(current);

current = new Type(*current);

}

void Commit() { history.DeleteAll(); }

void PopImage() // Вернуться на один уровень

{

if (!history.Empty()) {

delete current;

current = history.Pop();

}

}

void Rollback() // Вернуться к самому старому образу

{

Type* old = history.Pop();

Type* oldere = NULL;

if (old != NULL) { // Хотя бы один раз

while ((older = history.Pop()) != NULL) {

delete old;

old = older;

}

delete current;

current = old;

}

}

Type* operator->() const { return current; }

};

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


Назад    Содержание    Далее    

Home  Создание сайтов  Учебник по записи CD  Справочник Web дизайнера Самоучитель IE PHP и MySQL Компьютерные сети С++ E-mail me

Copyright 2007. Климов Александр. All Right Reserved.
Hosted by uCoz