Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

Откатываемый (undoable) класс - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ ComboBox + Button http://www.cyberforum.ru/cpp/thread105058.html
На форме имеется ComboBOx с 7 пунктами и две кнопки "Да" и "Нет" При последовательном ответе на все 7 вопросв кнопкой "Да" должно появится сообщение обезьяна съела банан,а если хотябы раз был ответ...
C++ Хуки мыши Такая проблема, пытаюсь написать хук для мыши, вроде событие отлавливается, библиотека отлично подключается, но функция которая должна возвращать указатель на структуру MOUSEHOOKSTRUCT, возвращает... http://www.cyberforum.ru/cpp/thread104861.html
GUI-программирование. Какая библиотека лучше? C++
Здравствуйте! Я знаю "консольный" C++, теперь хочется освоить какую-нибудь библиотеку или технологию визуального программирования. Подскажите, кто знает, что лучше выбрать и что сейчас востребовано?...
C++ Нужен совет с Canvas
Доброго времени суток, Нужен совет, через чего сделать следующее Дано: картинка с нарисованными объектами разной формы Необходимо: при нажатии на какой либо объект его выделить на самой картинке.....
C++ Mac OS Timers http://www.cyberforum.ru/cpp/thread103781.html
Доброго времени суток. Есть ли какие-то средства(чистый С) для работы с таймерами под Мак(аналоги timer_create или SetTimer, возможно, мультимедийные таймеры)? Или все же придется писать...
C++ Ring0 Кто-нибудь задавался вопросом работы с уровнем доступа ядра. Я так понял в windows есть 3 режима обработки приложений! и Ring0 имеет самые высокие привилегии. Если кто-то имеет опыт в этой области,... подробнее

Показать сообщение отдельно
volovzi
267 / 169 / 8
Регистрация: 14.03.2010
Сообщений: 501

Откатываемый (undoable) класс - C++

16.03.2010, 22:07. Просмотров 434. Ответов 6
Метки (Все метки)

Решил тут сделать универсальный интерфейс "откатываемости", который можно было бы прикрутить к любому классу. Идея в том, чтобы, унаследовав свой класс от некоторого класса Undoable, получить возможность сохранять, отменять и повторять изменения, произошедшие с классом. Ну, как undo/redo в любой программе.
Но смысл именно в универсальности, т.е. отменять действия не на уровне приложения, а на уровне каждого отдельного класса, которому такая функциональность необходима.

Первый вариант я сделал. Но результат пока что не тот, который хотелось бы видеть. Функциональность я реализовал, но для её получения мне необходимо наследование "наоборот", т.е. унаследовать не мой класс от класса Undoable, а Undoable от моего класса.
Это решение по-своему хорошо, но мне всё-таки хотелось поместить Undoable на вершину иерархии. Не подкинете идейку?

Исходный код прилагается.

Undoable.h

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/* Данный файл содержит описание класса Undoable, расширения, дающего возможность
любому классу запоминать и восстанавливать свои состояния. */
 
#include <vector>
#import "vectorServices.h"
 
template <class T>
class Undoable : public T {
    typedef std::vector<T *> TPointerArray;
    typedef typename TPointerArray::iterator TPointerArrayIterator;
 
public:
    Undoable () {}
    ~Undoable () { deleteVector(versions); }
    
    /* Сохраняет текущее состояние объекта. Если итератор "currentVersion"
    установлен не на конец массива копий состояний, то все последующие
    сохранённые состояния удаляются и в конец добавляется новое
    сохранённое состояние. */
    void save () {
        T * newObject = new T(*this);
    
        if (!versions.empty()) versions.erase(currentVersion + 1, versions.end());
        versions.push_back(newObject);
        currentVersion = versions.end() - 1;
    }
    /* Пытается откатить состояние объекта к предыдущему сохранённому.
    Если объект находится в своём начальном состоянии, т.е. в первом из
    сохранённых, то никаких изменений не производится и возвращается
    "false". В противном случае объект трансформируется в своё предыдущее
    сохранённое состояние, и возвращается "true". */
    bool undo () {
        if (currentVersion > versions.begin()) {
            T::operator=(**--currentVersion);
            return true;
        } else return false;
    }
    /* Пытается вернуть состояние объекта к следующему сохранённому.
    Если текущее сохранённое состояние является последним из сохранённых,
    то никаких изменений не производится и возвращается "false". В противном
    случае объект трансформируется в своё следующее сохранённое состояние,
    и возвращается "true". */
    bool redo () {
        if (currentVersion < versions.end() - 1) {
            T::operator=(**++currentVersion);
            return true;
        } else return false;
    }
    /* Удаляет все сохранённые состояния, кроме текущего. */
    void clearUndoHistory () {
        if (!versions.empty()) {
            currentVersion = versions.erase(versions.begin(), currentVersion);
            versions.erase(currentVersion + 1, versions.end());
            currentVersion = versions.begin();
        }
    }
 
private:
    TPointerArray versions;
    TPointerArrayIterator currentVersion;
};


Пример использования

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#import "Undoable.h"
 
// UVector (undoable vector) — расширение стандартного вектора.
template <class T>
class UVector : public Undoable<std::vector<T> > {};
 
int main (int argc, char * argv[]) {
    UVector<int> v;
    
    randomVector(v, 10);
    showVector(v);
    v.save();
    
    v.erase(v.begin() + 3, v.end());
    showVector(v);
    v.save();
    
    v.undo();
    showVector(v);
    
    v.redo();
    showVector(v);
    
    return 0;
}
Результат выполнения:

3 6 7 5 3 5 6 2 9 1
3 6 7
3 6 7 5 3 5 6 2 9 1
3 6 7
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru