【问题标题】:store pointers to different types of classes in an std::unordered_map在 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

标签: c++ pointers polymorphism unordered-map


【解决方案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,但从它的外观来看 - 它运行良好。非常感谢您的宝贵时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-17
  • 2016-02-19
  • 1970-01-01
  • 2012-09-25
  • 1970-01-01
  • 2015-04-06
  • 2023-04-09
相关资源
最近更新 更多