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

Posted

技术标签:

【中文标题】在 std::unordered_map 中存储指向不同类型类的指针【英文标题】:store pointers to different types of classes in an std::unordered_map 【发布时间】:2016-11-27 14:49:04 【问题描述】:

我有需要对其进行操作的设备。我有一个基类BASE 和一个子类TYPE1。 每个设备都是TYPE1 的一个实例。这些由另一个类实例化,具体取决于 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 让我可以在需要时快速直接访问对象,如果我使用

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

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

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

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

我的问题:

如何修改

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

所以它接受所有类型的类,如

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

我对此感到困惑,虽然我认为我可以绕过它,但它会很快变得丑陋,我真的很想以一种干净的方式来做。我要问的可能吗?如果可以,请问怎么做?

【问题讨论】:

std::unordered_map &lt;std::string, BASE *&gt;? 使用std::unordered_map&lt;std::string, std::unique_ptr&lt;BASE&gt;&gt; @Arch 在正确的轨道上。 别担心。这个网站越来越糟糕,完全合理的问题因虚假原因而被否决。 @ZoOl007 acceptAnyTypeOfClass 适用于 c++17 标准的std::any,否则您可以回退到boost::any 【参考方案1】:

想到的第一个选项是使用指向基类的指针,因为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: 如果您动态创建设备对象,您可以考虑在映射中使用唯一或共享指针,以避免内存泄漏。

【讨论】:

好的,我会在下周晚些时候试一试。我会进行一些重组。同时:感谢您花时间给我一个明确的答案。在我开始工作后,我会接受你的回答。我确实动态地创建了对象,是的,但是我通过 valgrind 运行它并且结果很干净。谢谢你的提示。那将是我需要学习的列表中的下一个。 @ZoOl007:std::unique_ptr 不仅避免了内存泄漏,还避免了手动内存管理带来的各种令人讨厌的错误,包括许多未定义的行为(例如,删除两次、取消引用 nullptr 和等等)。 @Christophe 我设法根据您告诉我的内容对其进行了调整。我还不能端到端地测试 type2,但从它的外观来看 - 它运行良好。非常感谢您的宝贵时间。

以上是关于在 std::unordered_map 中存储指向不同类型类的指针的主要内容,如果未能解决你的问题,请参考以下文章

向 std::unordered_map 插入数据时访问冲突

两个 std::unordered_map 的交集

在 C++ std::unordered_map 中预分配桶

如何在 std::tuple 中合并 std::unordered_map?

在 std::unordered_map 中使用模板键

std::unordered_map::operator[] - 为啥有两个签名?