现在的位置: 首页 > 综合 > 正文

应用篇_撤销(Undo)和重做(Redo)的C++自动化实现(1)—交换函数swap功能的讨论

2013年10月20日 ⁄ 综合 ⁄ 共 6265字 ⁄ 字号 评论关闭

作者: 熊春雷
网站: http://www.autodev.net
Blog: http://blog.csdn.net/pandaxcl
EMail: pandaxcl@163.com
QQ: 56637059
版本: 0.01 于2007/09/25
目标: 所有C++爱好者
版权: 本文的版权归熊春雷所有

Warning

  1. 本文由熊春雷所写,绝对保证原创,在此特别严肃声明。

  2. 绝对不能容忍他人说本文为他所写以及其他的侵权行为。一旦发现,一定 尽本人最大的能力以法律的形式严追到底,决不妥协。

  3. 引用本文,要保证本文的完整性,不可以删除此处的声明,并且务必注明出处。

Tip

  1. 本文编写的所有代码可以用于任何用途(包括商业用途)。

  2. 用于商业用途的需要在最后发布的软件中声明借鉴了本文的思想。具体事 宜可以协商解决,(代码决不收取任何费用)。

  3. 其他事项可以和我联系,包括技术讨论等等:)或者直接登陆网站论坛: http://www.autodev.net

Note

  1. 本文受到了《C++设计新思维》和《产生式编程》两本书的影响,同时也查阅了大 量的资料,从Loki库和Boost库中也吸收了不少营养,特此感谢之。

  2. 本文由于处于原创阶段,难免会出现各种各样的错误。代码出现错误的可能性非常 小(本来想说为零的),因为文档和代码是严格同步的,这是由VST文本的include 所保证的,代码都是测试成功之后才发布的。

  3. 本文所编写的代码,经过了VC2005编译器和g++编译器的测试,并且都通过了。

  4. 本文还没有彻底完成,算是一个初级版本,未来还将继续完善。暂时发布出来是为 了预知读者群有多少,读者越多,我的成就感越强,写作的时候也会更有动力:)

  5. 本文还会继续完善,欢迎各位读者的批评指正,也接受各种各样的建议,在权衡之 后以决定是否加入本书。

  6. 本书还没有最终完成,还会不断的进行完善,更新之后的内容将会发表于我的 网站我的博客。所以还需要读者多多关心本文的进展:)

Warning

  • 本文的有效篇幅仅仅局限于基础篇,之后的文档还仅仅只是一种创意记录,

  • 不保证正确性,特此提醒。

Contents


交换函数swap功能的讨论

在撤销和重做的实现过程中,总会出现各种各样的特殊情况和特殊技巧来实现撤销和重做 功能,由于本系列文档实现的是采用了一般化的方法实现了撤销和重做框架!所以就要思 考这样的问题:采用取巧的方法是否一定比这里通用的方法在时间和空间上面高效呢?本 文就是通过讨论一个基本的交换函数来作为类比,虽然不是很有说服力的解释,但是也说 明了不少的问题!

下面是经典的交换函数的两种实现方式:

采用中间变量的交换过程:

 int a = 10;
 int b = 20;
 // 需要第三个变量进行中转的交换过程
 int t;// 中转变量
 t = a;// 执行之后 a= 10 b= 20 t= 10
 a = b;// 执行之后 a= 20 b= 20
 b = t;// 执行之后 a= 20 b= 10

这就类似于有一杯橙汁(a)和一杯牛奶(b),要想把两个杯子中的饮料进行置换,就必须借 助于第三支空杯子(t)。交换的过程如下:

  1. 把橙汁(a)导入空杯子(t)中

  2. 把牛奶(b)导入盛橙汁的杯子(a)中

  3. 把空杯子(t)中的橙汁倒入盛牛奶的杯子(a)中

在上面的讨论过程中,假设了三个杯子的大小一样,其实这种假设是不必要的!特别需要 注意的是,这里的这个过程可以很容易的实现逆操作

下面再来看看采用另外的一种假设的交换过程:

 int a = 10;
 int b = 20;
 // 不需要第三个变量进行中转的交换过程
 a = a+b;// 右边a=10 b=20 执行之后 a= 30 b=20
 b = a-b;// 右边a=30 b=20 执行之后 a= 30 b=10
 a = a-b;// 右边a=30 b=10 执行之后 a= 20 b=10

从上面的交换过程可以看出,并没有采用第三个变量,而是直接采用了两个变量的自身! 这其实就是假设了:装橙汁和装牛奶的两个杯子都最多只装了一半!交换过程如下:

  1. 将牛奶倒入盛橙汁的杯子中

  2. 从1中的混合溶液中萃取出橙汁,放入盛牛奶的杯子中

上面的这个萃取过程是可不是那么容易实现的,这是由物理特性和化学特性决定 的!但是把上面的牛奶和橙汁换成水和汽油,那么实现起来就容易多了!当然是牛奶换成 水,橙汁换成汽油啦:)不过还要注意的是,上面的那个数学过程是可以实现可逆操 作的,但是后面的那个物理过程却很难实现逆操作

从上面的两种交换过程可以看出:虽然可以采用一些特定的技巧(例如第二种交换方法) 实现不采用第三个量实现交换,但是这种交换过程的限制却太多了,不容易推广使用!此 外这种非常有技巧的交换过程的逆操作的实现也是非常困难的,不可能有比较通用的方法 实现逆操作的!

鉴于此,第一种方法虽然采用了第三个变量实现交换,但是这种方法有着下面的种种优势:

  1. 交换过程可以非常容易的实现

  2. 交换过程的逆操作也可以很容易的实现

  3. 采用第三个变量实现交换的过程并不比其他的特定技巧实现的交换过程的方法占用 的资源多!

关于第3点,可以这样解释:第一种交换方法所用的三个杯子可以是一样大,而第二种交换 方法的两个杯子,先倒出牛奶的杯子可以只有装橙汁的杯子的容积的一半大小!如果装牛 奶的杯子和第一种方法中的杯子大小一致,那么两种方法的杯子的容积是一样的!由此可 见,采用特定的方法并不一定省资源:(

有了上面的讨论,可以看出,第一种交换方法是一种非常好的通用的交换方法:)撤销和 重做的本质就是一种交换过程,下面的内容都是围绕这种方法来讨论的:)

【上篇】
【下篇】

抱歉!评论已关闭.