在 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
的子代,但类型不同。
TYPE1
和 TYPE2
都实现了相同的方法 - 它们的功能不同 - 但产生相同的结果
我的问题:
如何修改
std::unordered_map <std::string, TYPE1 *> myDevices;
所以它接受所有类型的类,如
std::unordered_map <std::string, acceptAnyTypeOfClass *> myDevices;
我对此感到困惑,虽然我认为我可以绕过它,但它会很快变得丑陋,我真的很想以一种干净的方式来做。我要问的可能吗?如果可以,请问怎么做?
【问题讨论】:
std::unordered_map <std::string, BASE *>
?
使用std::unordered_map<std::string, std::unique_ptr<BASE>>
。
@Arch 在正确的轨道上。
别担心。这个网站越来越糟糕,完全合理的问题因虚假原因而被否决。
@ZoOl007 acceptAnyTypeOfClass
适用于 c++17 标准的std::any
,否则您可以回退到boost::any
。
【参考方案1】:
想到的第一个选项是使用指向基类的指针,因为TYPE1
和TYPE2
对象都是BASE
对象:
std::unordered_map <std::string, BASE*> myDevices;
那么问题是如何区分TYPE1*
指针和TYPE2*
指针?
由于TYPE1
和TYPE2
都实现了相同的方法,最好的方法可能是使用多态,使用虚函数:
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 插入数据时访问冲突
在 C++ std::unordered_map 中预分配桶