在 std::unordered_map 中存储指向不同类型 类 的指针

store pointers to different types of classes in an std::unordered_map

我有需要进行操作的设备。我有一个基地 class BASE 和一个 child class TYPE1。 每个设备都是 TYPE1 的实例。这些由另一个 class 实例化,具体取决于 xml 配置文件中存在的内容。

class BASE {
public:
    BASE();
    virtual ~BASE();
};

class TYPE1 : public BASE {
public:
    TYPE1();
};

现在我将指向这些实例的指针存储在一个 std::unordered_map 中,定义为:

std::unordered_map <std::string, TYPE1 *> myDevices;

其中 std::string 是配置文件中也使用的标识键。

如果我需要,std::unordered_map 可以让我快速直接访问 object,如果我使用

遍历它,我可以方便地在所有设备上执行相同的操作
for ( auto& elem : myDevices ) {
    //do stuff
}

设备的顺序并不重要,因此 std::unordered_map。 我在整个代码中广泛使用它。

现在我需要一个 TYPE2,它也是 BASE 的 child,但类型不同。

TYPE1TYPE2 都实现了相同的方法 - 它们的功能不同 - 但产生相同的结果

我的问题:

如何修改

std::unordered_map <std::string, TYPE1 *> myDevices; 

所以它接受所有类型的 classes 像

std::unordered_map <std::string, acceptAnyTypeOfClass *> myDevices;

我受阻了,虽然我认为我可以绕过它,但它很快就会变得丑陋,我真的很想以一种干净的方式来做。我问的是可能的吗?如果可以,请问如何?

想到的第一个选项是使用指向基 class 的指针,因为 TYPE1TYPE2 对象都是 BASE 对象:

std::unordered_map <std::string, BASE*> myDevices;

问题是如何区分 TYPE1* 指针和 TYPE2* 指针?

由于 TYPE1TYPE2 都实现了相同的方法,最好的方法可能是使用多态性,使用虚函数:

class BASE {
public:
    BASE();
    virtual void doSomething()=0;  
    virtual ~BASE();
};

class TYPE1 : public BASE {
public:
    TYPE1();
    void doSometing() override { /* the code for TYPE 1 devices*/ }
};

class TYPE2 : public BASE {
public:
    TYPE2();
    void doSometing() override { /* the code for TYPE 2 devices*/ }
};

然后您可以调用函数而不必担心基础对象的真实类型:

std::unordered_map <std::string, BASE*> myDevices;
...
for (auto& elem : myDevices ) {
    elem->doSomething();  
}

P.S: 如果动态创建设备对象,可以考虑在映射中使用唯一或共享指针,以避免内存泄漏。