如何将不同的 C++ classes 映射到枚举 class 值

How to map different C++ classes to enum class values

我生成消息,每个消息都由一个对象接收,由 enum class 成员选择:

enum class ReceiverID
{
    R1,
    R2,
    MAX_NUM_RECEIVERS
};

struct Msg
{
    ReceiverID _receiverID;
    Data _data;
};

接收的 classes 存储在一个数组中。枚举成员索引数组以访问接收对象:

void receive(const Msg& msg)
{
    const size_t arrIndex = static_cast<size_t>(msg._receiverID);
    
    if(nullptr == _array[arrIndex])
    {
        _array[arrIndex] = ???  // How do I associate the enum to the class?
    }
    
     _array[arrIndex].processMsg(msg);
}

可能是接收对象丢失了。如果发生这种情况,我想使用枚举来实例化丢失的对象。但是,这需要将枚举值映射到接收对象类型。

如何将 class 映射到每个枚举? (对于所有枚举)。

如果添加了新的枚举但没有相应的接收器,我想生成一个编译器错误class。

更新

接收对象是多态的,因此有一个基数 class。数组是:

std::array<Base*, MAX_NUM_RECEIVERS> _array;

(删除了 unique_ptr 以简化问题)

与其拥有一个全局的 std::array<Base*, MAX_NUM_RECEIVERS> _array; 然后根据需要懒惰地填写它,我相信正常的做法是在构建时填写它:

std::array<Base*, MAX_NUM_RECEIVERS>& _array() {
    //use a method to bypass 
    static std::array<Base*, MAX_NUM_RECEIVERS> array = make_array();
    return array;
}
std::array<Base*, MAX_NUM_RECEIVERS> make_array() {
    std::array<Base*, MAX_NUM_RECEIVERS> array;
    array[static_cast<size_t>(R1)] = &myR1ProcessorObject();
    array[static_cast<size_t>(R2)] = &myR2ProcessorObject();
    return array;
}

那你的接收方法就简单了:

void receive(const Msg& msg)
{
    const size_t arrIndex = static_cast<size_t>(msg._receiverID);
    assert(arrIndex< MAX_NUM_RECEIVERS);
     _array()[arrIndex].processMsg(msg);
}

为了即时创建对象,我们可以使用某种工厂方法,例如:

//In the Base class:
static Base* createReceiver(ReceiverID recvID) //static member function
{
    switch (recvID)
    {
        case ReceiverID::R1: return new R1Receiver();
        case ReceiverID::R2: return new R2Receiver();
        //...
        default: throw std::logic_error("Invalid ReceiverID");
    }
}

//...
void receive(const Msg& msg) except(true)
{
    const size_t arrIndex = static_cast<size_t>(msg._receiverID);
    if(nullptr == _array[arrIndex])
    {
        _array[arrIndex] = Base::createReceiver(msg._receiverID);
    }    
    _array[arrIndex]->processMsg(msg);
}