c++ - 在 C++ 中创建动态类型

标签 c++ templates design-patterns inheritance

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

简而言之,这是我当前的实现:

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 std::make_unique<T>(); }
};

现在你有一个允许你注册这些的类工厂。

class VariantFactory
{
  public:
    VariantFactory()
    {
         // If you want, you can do all your Register() calls in here, and even
         // make the Register() function private.
    }

    template< uint8_t type, typename T >
    void Register()
    {
        Register( type, std::make_unique<Variantinator<T>>() );
    }

    std::unique_ptr<Variant> Create( uint8_t type )
    {
        TSwitchToVariant::iterator it = m_switchToVariant.find( type );
        if( it == m_switchToVariant.end() ) return nullptr;
        return it->second->Create();
    }

  private:
    void Register( uint8_t type, std::unique_ptr<VariantinatorBase>&& creator )
    {
        m_switchToVariant[type] = std::move(creator);
    }

    typedef std::map<uint8_t, std::unique_ptr<VariantinatorBase> > TSwitchToVariant;
    TSwitchToVariant m_switchToVariant;
};

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

VariantFactory factory;
factory.Register<0, VariantA>();
factory.Register<1, VariantB>();
factory.Register<2, VariantC>();

然后,你想调用它:

std::unique_ptr<Variant> thing = factory.Create( switchValue );

关于c++ - 在 C++ 中创建动态类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16047560/

相关文章:

c++ 这个参数在命令行中是什么意思? | grep MATCH >zout匹配

c++ - 具有可变数量的模板参数的简单方法

design-patterns - 设计模式的类别

oop - 如何实现功能共享相同逻辑的接口(interface)?

c++ - 调用虚拟方法的不同方式

c++ - 类中变量的属性似乎未声明

c++ - 使用 istream_iterator 范围构造时无法访问 vector

c++ - 向模板特化添加更多类型

c++ - 初始化忽略构造函数模板

c++ - 逻辑设计模式