#if 0
在上一章里面讨论了复合对象的问题。RoundRectangle类(b)方案是一个复合类方案,
从上一章的内容我们可以看出虽然实现了一个RoundRectangle类确实是一个复合类,但是
实现复合类是一个比较繁琐的事情,对于一个程序里面有很多这种类的情况,那么前一章
里面的编码过程将会是一个非常繁琐的体力劳动。在这一章里面将使用模板元编程将这种
繁琐的体力劳动自动化。
在给出实现之前我们还是先把问题弄清楚!所以必须先回答下面的几个问题:
(1)自动化的目标是什么?关于这个问题,从前一章可以看出:很显然将要给出一个通
用的复合对象类。那么这个最终的类名,我命名为:“compound”,因为这个词具有化合
物的意思。学过高中化学的都知道,化合物可以是一种单质。很显然这里的复合对象类自
身是一个完备的整体,这一点和单质的概念有点类似:)。
(2)这个复合对象类的输入参数是什么?从前一章可以得出:传入的参数当然是各个属
性的类型信息串。这种类型串正好可以使用模板元编程基础与应用的cons类型串来实现。
(3)这个复合对象类具备有那些操作?从前一章可以看出:复合对象类很显然应该具备
有三种操作,分别是创建(create)、修改(modify)和删除(remove)。其中创建操作将会在
复合对象创建的同时把所有的属性类型的对象也创建一份;修改操作则可以直接修改每一
个属性对象,这是通过属性类型的静态转型来实现的;删除操作将会在复合对象删除之前
把所有的属于该复合对象的属性对象全部删除。
(4)这个复合对象类的操作应该遵守什么约定?这一点需要特殊说明,为了使得本章所
介绍的复合对象类尽可能的简单而且通用,在这里我直接采用可以通过索引号访问自动生
成的变量的代码产生类scatter,这一点可以参见我得“C++自动化(模板元)编程基础与应
用”系列文章。这样之后就可以直接使用许许多多的C++模板元高级技术来实现我们要求的
功能啦:)。
现在问题已经比较明了了,下面看看CODE1的实现和测试代码:
#endif
#ifdef CODE1
#include <iostream>
#include "command.h"
#include "center.h"
//复合对象类的实现
#include "meta.h"//模板元编程基础与应用讨论的内容
#include "identifier.h"//复合对象类必须使用这个类
namespace pandaxcl{
//scatter产生代码需要的基元模板,用来生成属性
template <class T> struct compound_unit
{
//通过下面的代码就可以解释为什么前面在讨论标识号类的时候必须采用
//和类型相关的标识号,而不能够有通用的标识号类了:)
identifier<T> ID;//属性对象的标识号
//在上面的标识号模板中使用默认的第二个模板参数类型long,这一点将
//会在后续的进行弹性相关的讨论的文章中讨论。在这里就是先要让代码
//能够正常运行起来:),通常来说只需要使用默认的参数就可以正常使用
//了,但是对于特殊的情况也不能不进行讨论:)。
};
//利用scatter来生成代码创建自动化类,并通过模板元编程来实现操作代码的自动化
//这样之后这整个类就成了名副其实的自动化类了:)
template<class Cons>class compound
:public scatter<Cons,pandaxcl::compound_unit>
{
public:
typedef Cons cons_type;
typedef scatter<Cons,pandaxcl::compound_unit> scatter_type;
//复合对象的创建函数的自动化实现
template <class ControlType,class CID>
static void create(ControlType&C,const CID&ID)
{
typedef container<CID,compound> TCT;//复合对象容器类型
compound tmp;//定义一个临时的复合类对象
C.record();
//自动化创建所有的子图元
ENVIRONMENT<ControlType> e(C,tmp);
LOOP<CREATE,0,length<cons_type>::value,1>::execute(e);
//然后创建自身,由于create命令和这里的create函数同名,所以
//用名字空间进行限制选择create命令
C.execute(new pandaxcl::create<TCT>(C,ID,tmp));
C.stop();
}
//下面的函数是用来修改复合对象的属性的修改函数
template <size_t i,class PropertyType,class ControlType,class CID>
static void modify(ControlType&C,const CID&ID,const PropertyType&OM)
{
typedef container<CID,compound> TCT;//复合对象容器类型
typedef identifier<PropertyType> PID;//属性对象使用的标识符类型
typedef container<PID,PropertyType> PCT;//属性对象使用的容器类型
typedef compound_unit<PropertyType> UTT;//确保每行代码不至于过长
const compound &S = static_cast<TCT&>(C).reference(ID);
const UTT &P = static_cast<const UTT&>(field<i>(S));
//由于modify命令和这里的midify函数同名,所以用名字空间
//进行限制选择modify命令
C.execute(new pandaxcl::modify<PCT>(C,P.ID,OM));
}
//复合对象的删除函数的自动化实现
template <class ControlType,class CID>
static void remove(ControlType&C,const CID&ID)
{
//因为删除复合对象是一步操作,所以需要将所有的子元素的删除合并
//成为一个复合命令,使之表现的比较象简单对象的删除操作一样。
typedef container<CID,compound> TCT;//复合对象容器类型
const compound&S = static_cast<TCT&>(C).reference(ID);
C.record();
//自动化删除所有的子图元
ENVIRONMENT<ControlType> e(C,S);
LOOP<REMOVE,0,length<cons_type>::value,1>::execute(e);
//然后删除自身,由于remove命令和这里的remove函数同名,所以
//用名字空间进行限制选择remove命令
C.execute(new pandaxcl::remove<TCT>(C,ID));
C.stop();
}
private:
//CREATE和REMOVE都需要传入的动态参数结构
template<class ControlType> struct ENVIRONMENT
{
typed
撤销和重做(Undo和Redo)的C++完美实现(7-A)
最新推荐文章于 2023-04-20 09:27:31 发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)