在C中创建动态类型

我正在编写一个通用软件,将加载到同一基本硬件的许多不同的变体.它们都具有相同的处理器,但具有不同的外设和自己的功能需要执行.该软件将通过读取硬件开关值来知道应该运行哪个变体.

这是我目前的实现:

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语句创建新的对应类.

问题是有很多变种我必须处理.目前约有15个,有可能在不久的将来再增加20-30个.我真的来鄙视开关数十行的switch语句,所以我真的在寻找一个更好的方式来做到这一点,可能是通过模板.

我想要使​​用我的硬件值查找类型并使用该类型来创建我的新对象.理想情况下,当我添加一个新的变体时,我创建了一个新的类,将该类添加到查找表中,具有匹配的硬件值,而且很好.

这是可能的吗这里有什么好的解决方案?

解决方法

如上所述,你做一个工厂,但不一定是天真的switch语句.您可以做一个模板类来创建相关对象,并将它们动态地添加到工厂.
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; }
};

现在你有一个班级工厂,让你注册这些.

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;
};

在程序开始时,创建工厂并注册您的类型:

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&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...