Dan*_*Dan 10 c++ inheritance templates design-patterns
我正在编写一个通用软件,它将加载到同一基本硬件的许多不同变体上.它们都具有相同的处理器,但具有不同的外围设备和它们自己需要执行的功能.通过读取硬件开关值,软件将知道应该运行哪个变体.
这是我目前的实现,简而言之:
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();
}
Run Code Online (Sandbox Code Playgroud)
现在这个工作得很好.我读取了硬件值并使用switch语句来创建新的相应类.
问题是我必须处理很多变种.目前约有15个,有可能在不久的将来再增加20-30个.我真的很鄙视那些运行数百行的switch语句,所以我真的在寻找一种更好的方法,可能是通过模板.
我希望能够使用我的硬件值来查找类型并使用该类型来创建我的新对象.理想情况下,当我添加一个新变体时,我创建了新类,将该类类型添加到我的查找表中,并使用匹配的硬件值,这样做很好.
这有可能吗?这里有什么好的解决方案?
pad*_*ddy 16
如上所述,您是一个工厂,但不一定是天真的开关语句.你可以做的是创建一个模板类来创建相关对象并动态地将它们添加到你的工厂.
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 std::make_unique<T>(); }
};
Run Code Online (Sandbox Code Playgroud)
现在你有一个允许你注册这些的类工厂.
class VariantFactory
{
public:
VariantFactory()
{
// If you want, you can do all your Register() calls in here, and even
// make the Register() function private.
}
template< uint_8 type, typename T >
void Register()
{
Register( type, std::make_unique<Variantinator<T>>() );
}
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:
void Register( uint_8 type, std::unique_ptr<VariantinatorBase>&& creator )
{
m_switchToVariant[type] = std::move(creator);
}
typedef std::map<uint_8, std::unique_ptr<VariantinatorBase> > TSwitchToVariant;
TSwitchToVariant m_switchToVariant;
};
Run Code Online (Sandbox Code Playgroud)
在程序开始时,创建工厂并注册您的类型:
VariantFactory factory;
factory.Register<0, VariantA>();
factory.Register<1, VariantB>();
factory.Register<2, VariantC>();
Run Code Online (Sandbox Code Playgroud)
然后,你要打电话给它:
std::unique_ptr<Variant> thing = factory.Create( switchValue );
Run Code Online (Sandbox Code Playgroud)