按照类型名称动态创建对象
2010-10-15 09:08:18 来源:Web开发网然而,在上面我故意忽略了一个问题,设备类(IM9001, IM9002等)并没有提供默认构造函数,因此实际上这些代码是无法通过编译的。可以通过修改接口的设计来避开这个问题,即增加默认构造函数和指定端口的构造函数。虽然这和实际情况不符(因为这里的设备不支持热插拔,不能再程序运行时更换连接的端口),但是为了便于实现也是可以接受的。
但是,更隐蔽的一个缺陷是,如果设备类本身的尺寸较大,那么为所有支持的型号创建实例,将增加空间负荷,而实际上实际使用的设备可能仅仅只用到其中的两三个型号而已。
从这个角度看,型号映射表中应该映射的是类的创建器,而不是类的实例本身,而类的创建器几乎没有什么空间负担。
这里有一个极其简单的创建器,
template <class T>
IntelligentMotor* IntelligentMotorCreator(const std::string& port_name)
{
return new T(port_name);
}
现在我们的映射表变成了
typedef IntelligentMotor* (*Creator)(const std::string& port_name);
struct Map
{
const std::string ModelName;
Creator DeviceCreator;
};
Map model_table[]=
{
{"IM9001",&(IntelligentMotorCreator<IM9001>)},
{"IM9002",&(IntelligentMotorCreator<IM9002>)}
//...
};
而ClassByName则变成了
IntelligentMotor* ClassByName(const std::string& model_name,
const std::string& port_name)
{
for (int i=0;i<sizeof(model_table)/sizeof(Map);++i)
{
if (model_name==model_table[i].ModelName)
return (*model_table[i].DeviceCreator)
(port_name);
}
throw "不支持该型号的设备。";
}
更多精彩
赞助商链接