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

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

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ ComboBox + Button http://www.cyberforum.ru/cpp/thread105058.html
На форме имеется ComboBOx с 7 пунктами и две кнопки "Да" и "Нет" При последовательном ответе на все 7 вопросв кнопкой "Да" должно появится сообщение обезьяна съела банан,а если хотябы раз был ответ "нет" то все начинается по новой!
C++ Хуки мыши Такая проблема, пытаюсь написать хук для мыши, вроде событие отлавливается, библиотека отлично подключается, но функция которая должна возвращать указатель на структуру MOUSEHOOKSTRUCT, возвращает структуру вверх ногами, координаты мыши почему-то лежат в параметрах wHitTestCode и dwExtraInfo, а в x,y лежит int значение, похожее на указатель, код dll выглядит так //mhook.h #include... 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. Просмотров 430. Ответов 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
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru