C++ 如何存储一个;“对象类型”;在std::map中?
长篇介绍,问题在最后:C++ 如何存储一个;“对象类型”;在std::map中?,c++,C++,长篇介绍,问题在最后: 假设我有一个创建接口的基类 class base { public: virtual ~base(); virtual void calc( int* variables ) = 0; } 还有一些继承的类完成了这项工作(这里只显示了两个): 最后是一些使用这种结构的代码: base* task[2]; task[0] = new add( 0, 1, 2 ); task[1] = new inc( 3 ); int data[4]; /* ... */
假设我有一个创建接口的基类
class base
{
public:
virtual ~base();
virtual void calc( int* variables ) = 0;
}
还有一些继承的类完成了这项工作(这里只显示了两个):
最后是一些使用这种结构的代码:
base* task[2];
task[0] = new add( 0, 1, 2 );
task[1] = new inc( 3 );
int data[4];
/* ... */
for( int i = 0; i < 2; i++ )
task[i]->calc( data );
除了变得很难阅读之外,这只是一个线性搜索。因此,本着的精神,我想用std::map
(或hash-map…)替换线性搜索
经过长时间的介绍,我终于可以回答这个问题了:
如何定义和填充
std::map
,以便以这样一种方式存储对对象的引用(?),即我可以利用该信息在对象上动态创建该引用?
因此,通过上面的代码,我想做一些事情,最终看起来可能是这样的:
// define and fill
std::map< std::sting, ???? > lookup;
lookup["add"] = add;
lookup["inc"] = inc;
/* ... */
// use:
while( linesInConfigAvailable )
{
/* ... parse ... */
switch( params.size() )
{
case 1:
task[end] = new lookup[command]( params[0] );
break;
case 3:
task[end] = new lookup[command]( params[0], params[1], params[2] );
break;
}
}
//定义和填充
标准::映射<标准::sting,?>查找;
查找[“添加”]=添加;
查找[“inc”]=inc;
/* ... */
//使用:
while(LinesInConfig可用)
{
/*…解析*/
开关(params.size())
{
案例1:
任务[结束]=新查找[命令](参数[0]);
打破
案例3:
任务[结束]=新查找[命令](参数[0],参数[1],参数[2]);
打破
}
}
PS:到目前为止,我的代码中不需要RTTI。如果能保持这样的状态那就太好了…好吧,你不能。在C++中,类不是对象,它们更像是一个抽象结构,只存在于编译器编译数据时的工作数据中。 但是,您可以使用给定的签名创建所谓的工厂函数:
class A : public Base
{
public:
static Base* Create() { return new A; }
};
class B : public Base
{
public:
static Base* Create() { return new B; }
};
...
编辑:如果“创建”函数是这样统一的,您当然可以制作一个模板
然后,您可以在映射中存储函数指针:
typedef Base* (*FactoryType)();
std::map< std::string, FactoryType >
lookup["A"] = A::Create;
lookup["B"] = B::Create;
@Chris为了符合样式指南,您应该以大写字母开头所有类名。例如
base
到base
@MartyE这是来自“通用”风格指南吗?(好吧,真实代码中的类名已经以大写字母开头了——但我不确定其余的是否符合要求,而且由于它是OSS,我希望与其他人期望的一样…@MartyE Bullocks。停止传播毫无意义的“建议”@Chris我从谷歌的风格指南中推荐这一建议,尽管它不是通用的。我之所以提到这一点,是因为它在通读时绊倒了我(这是一个类定义,也是类的一个对象)。@MartyE Google的风格指南是谷歌风格的指南。谷歌的风格就是谷歌的风格。它不打算在谷歌之外使用。它不是一份“最佳实践”文件。事实上,它包含了一些与广泛接受的最佳实践背道而驰的观点,因为它们自身的内部组织原因通常不适用于谷歌以外的公司。在typedef Base*(*FactoryType)(
)中typedef
做什么?感谢Christian,这就是我一直在寻找的解决方案,我现在正是这么做的(稍微修改以处理构造函数参数)
class A : public Base
{
public:
static Base* Create() { return new A; }
};
class B : public Base
{
public:
static Base* Create() { return new B; }
};
...
typedef Base* (*FactoryType)();
std::map< std::string, FactoryType >
lookup["A"] = A::Create;
lookup["B"] = B::Create;
task[end] = lookup[command]();