问题描述
我正在写一个通用软件,将加载到同一个基本硬件的许多不同变体。它们都具有相同的处理器,但具有需要执行的不同外设和它们自己的功能。软件将通过读取硬件开关值知道应该运行哪个版本。
I'm writing a piece of generic software that will be loaded on to many different variants of the same basic hardware. They all have the same processor, but with different peripherals and their own functions that need to be carried out. The software will know which variant it should run by reading a hardware switch value.
这是我目前的实现:
class MyBase
{
public:
MyBase() { }
virtual run() = 0;
}
class VariantA : public MyBase
{
public:
VariantA () { }
virtual run()
{
// Run code specific to hardware Variant-A
}
}
class VariantB : public MyBase
{
public:
VariantB () { }
virtual run()
{
// Run code specific to hardware Variant-B
}
}
void main()
{
MyBase* variant;
uint_8 switchValue = readSwitchValue();
switch(switchValue)
{
case 0:
variant = new VariantA();
break;
case 1:
variant = new VariantB();
break;
}
variant->run();
}
现在这个工作很好。我读硬件值,并使用switch语句创建新的相应的类。
Now this works just fine. I read the hardware value and use a switch statement to create the new corresponding class.
问题是有很多变体我必须处理。目前约有15个,有可能在不久的将来再增加20-30个。我真的来鄙视switch语句运行数百行,所以我真的寻找一个更好的方法来做这个,可能通过模板。
The problem is that there are a lot of variants I have to deal with. Currently about 15, with the potential to add another 20-30 in the near future. I have really come to despise switch statements that run for hundreds of lines, so I'm really looking for a better way to do this, probably through templates.
我想以便能够使用我的硬件值来查找类型并使用该类型来创建我的新对象。理想情况下,当我添加一个新的变体,我创建新类,添加该类类型到我的查找表与它的匹配的硬件值,这是很好去。
I want to be able to use my hardware value to look up a type and use that type to create my new object. Ideally when I add a new variant, I create the new class, add that class type to my lookup table with it's matching hardware value, and it's good to go.
这可能吗?这里有什么好的解决方案?
Is this possible at all? What's a good solution here?
推荐答案
如上所述,你做一个工厂,你可以做的是创建一个模板类来创建相关的对象并动态添加到你的工厂。
As stated, you make a factory, but not necessarily with naive switch statements. What you can do is make a template class to create the relevant object and dynamically add these to your factory.
class VariantinatorBase {
public:
VariantinatorBase() {}
virtual ~VariantinatorBase() {}
virtual std::unique_ptr<Variant> Create() = 0;
};
template< class T >
class Variantinator : public VariantinatorBase {
public:
Variantinator() {}
virtual ~Variantinator() {}
virtual std::unique_ptr<Variant> Create() { return new T; }
};
现在你有一个类工厂,允许你注册这些。
Now you have a class factory that allows you to register these.
class VariantFactory
{
public:
VariantFactory()
{
// If you want, you can do all your Register() calls in here, and even
// make the Register() function private.
}
void Register( uint_8 type, std::unique_ptr<VariantinatorBase> creator )
{
m_switchToVariant[type] = creator;
}
std::unique_ptr<Variant> Create( uint_8 type )
{
TSwitchToVariant::iterator it = m_switchToVariant.find( type );
if( it == m_switchToVariant.end() ) return nullptr;
return it->second->Create();
}
private:
typedef std::map<uint_8, std::unique_ptr<VariantinatorBase> > TSwitchToVariant;
TSwitchToVariant m_switchToVariant;
};
在程序开始时,创建工厂并注册类型:
At the beginning of your program, create the factory and register your types:
VariantFactory factory;
factory.Register( 0, new Variantinator<VariantA> );
factory.Register( 1, new Variantinator<VariantB> );
factory.Register( 2, new Variantinator<VariantC> );
稍后,您需要呼叫:
std::unique_ptr<Variant> thing = factory.Create( switchValue );
这篇关于在C ++中创建动态类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!