编辑器程序少不了要支持undo, redo功能,如何实现?本文就是参考了设计模式中给出的思路实现了一个。
这里主要用到了两个模式:命令(command)模式, 备忘录(memento)模式
所谓编辑,功能上可以分成3个原子操作:添加新内容,编辑已有内容,删除已有内容, 因此编辑功能3个command实现,AddCommand, EditCommand, DeleteCommand. 这3个命令实现了相同的接口do, undo.
先说一下代码的风格,自从使用WTL,就喜欢上了WTL的代码风格,本文就是仿照WTL风格写的.
先看一下Command的接口:
- class CCommand
- {
- public:
- virtual ~CCommand();
- public:
- virtual bool Do() = 0;
- virtual bool Undo() = 0;
- virtual bool CanUndo() = 0;
- };
AddCommand, EditCommand, DeleteCommand都实现了这个接口类。
下面WTL风格代码开始了:
先留个空架子
- template<class TBase/*where TBase : public CCommand*/>
- class CCommandImplBase : public TBase
- {
- //先空着,以后留着扩展
- };
下面是主要实现:用到了event, 当Command执行时会触发event,你可以在时间里做一些诸如试图更新, 所谓event,跟C#里的事件相似,感兴趣的可以看我前面的文章用C++模拟C#事件机制。
- template< class T, class TBase = CCommand, class TTraits = CommandTraits<T> >
- class CCommandImpl : public CCommandImplBase<TBase>
- {
- public:
- typedef TTraits::CmdEvent CmdEvent;
- typedef CmdEvent::EventHandler EventHandler;
- public:
- CCommandImpl(typename CmdEvent::EventArgs/* const& */args) : m_Args(args)
- {
- #if (_MSC_VER >= 1300)
- //COMPLIE_ASSERT(IsPointer(args));
- bool bRet = TypeTraits<CmdEvent::EventArgs>::IsPointer();
- #endif
- }
- virtual ~CCommandImpl()
- {
- }