|
Класс LockPtr Ага! Мы подошли к центральной идее всей концепции - указателям, которые разрешают обновление указываемого объекта. Предтранзакционный (предназначенный для отмены) образ хранится в ConstPtr, а текущий обновленный образ доступен только через LockPtr. Класс LockPtr содержит уже знакомые функции Rollback() и Commit(). В функции Snapshot() нет необходимости, поскольку LockPtr при необходимости создает образы в операторе ->. template <class Type> class LockPtr : public Lock { friend class ConstPtr<Type>; private: ConstPtr<Type>* master_ptr; Type* new_image; Transaction* transaction; LockPtr(Transaction* t, ConstPtr<Type>* cp); virtual ~LockPtr(); virtual void Rollback(); virtual void Commit(); public: Type* operator->() const { return new_image; } }; template <class Type> LockPtr<Type>::LockPtr(Transaction* t, ConstPtr<Type>* cp) : transaction(t), master_ptr(cp), new_image(new Type(*(cp->old_image))) { } template <class Type> LockPtr<Type>::~LockPtr() { // В сущности происходит откат delete new_image; // Отказаться от изменений master_ptr->lock = NULL; // Оставить ConstPtr } template <class Type> void LockPtr<Type>::Rollback() { delete new_image; new_image = new Type(*(master_ptr->old_image)); } template <class Type> void LockPtr<Type>::Commit() { delete master_ptr->old_image; master_ptr->old_image = new_image; // Переместить в master_ptr new_image = new Type(*new_image); // Нужна новая копия } Деструктор объявлен закрытым, чтобы никто не мог напрямую удалить LockPtr. Вместо этого транзакция-владелец должна сделать это через базовый класс Lock. Функции Rollback() и Commit() объявлены виртуальными, чтобы с их помощью можно было решать задачи, относящиеся к конкретному типу (например, создание и уничтожение образов). Обе функции после завершения оставляют ConstPtr заблокированным. |
Copyright 2005. Климов Александр. All Right Reserved.