WEB开发网
开发学院软件开发C++ 按照类型名称动态创建对象 阅读

按照类型名称动态创建对象

 2010-10-15 09:08:18 来源:Web开发网   
核心提示:3 扩充我们现在有了实用的ClassByName,但是还有几个小问题期待我们去解决,按照类型名称动态创建对象(4),首先,如果查找成为一种费时的操作,是构造可存储的对象库(IO object libaray)的常用方法,希望在自己开发的应用框架中提供对象持久性(Persistance)的用户,那么我们可以使用一个关联数

3 扩充

我们现在有了实用的ClassByName,但是还有几个小问题期待我们去解决。

首先,如果查找成为一种费时的操作,那么我们可以使用一个关联数组代替内建数组提供类型查找功能。也就是

typedef std::map<std::string,Creator> ClassLookupTable;
    ClassLookupTable model_lookup_table;
    for (int i=0;i<sizeof(ModelTable)/sizeof(Map);++i)
      model_lookup_table[ModelTable[i].ModelName]
        =ModelTable[i].DeviceCreator;

这时我们的最新版的ClassByName则拥有了略低的平均复杂度。

IntelligentMotor* ClassByName(const std::string& model_name,
      const std::string& port_name)
    {
      ClassLookupTable::const_iterator pos;
      pos=model_lookup_table.find(model_name);
      if (pos==model_lookup_table.end())
        throw "不支持该型号的设备。";
      return (*pos->second)(port_name);
    }

不过这里有一个设计上的决策需要使用者作出,因为这个版本需要更多的时间和空间建立快速查找表,这是一种“一次付出,多次分期摊还成本”的优化策略,必须根据实际情况决定。

其次,为了减低编译依赖性,可以将所有的代码封装成库(或者是共享库,如动态链接库DLL),只输出一个ClassByName接口,并单独提供协议类IntelligentMotor的接口,这样只要不改变协议类的接口,那么使用ClassByName的代码不需要因为增加新型号的设备而重新编译,如果是共享库的形式,那么甚至重新链接都不需要,只需要重新编译独立的设备型号库即可。

无论如何,还是必须手工的为支持每一个新的型号而需要手工修改类型创建器的表格。我实在无法使用模板来处理这种异常古怪的情况,不管是内建数组,还是标准容器,都无法处理异种类型混合的元素,只能使用基类指针或者所谓的泛型指针(void *),从类型安全性来说,向上转型(up-cast)的基类指针更为合适。这就隐含了一个限制,如果是一个任意类型的类型库系统,则必须要求建立严格的单根集成体系,然而据我所知,不管是Java还是VCL,都同样对此做出了限制,MFC似乎使用了宏,但是我不确定是否克服了这个挑战。

更一般化的动态创建对象技术,可以阅读Andrei Alexandrescu的<<Modern C++ Design>>一书,其中第八章Object Factory介绍了完整的动态创建对象的方法。从基本原理上来说,其中使用的技术和本文中的相类似,然而此书中的实现更加灵活、高效和通用。

4 应用

正如前面提起过的,本文介绍的技术,可以用于根据类型名称动态的创建该类型的实例。

典型的,这种动态创建类实例的方法,是构造可存储的对象库(IO object libaray)的常用方法,希望在自己开发的应用框架中提供对象持久性(Persistance)的用户,可以参考本文的技术。

上一页  1 2 3 4 

Tags:按照 类型 名称

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接