C++,Boost:如何在地图容器中存储抽象类型的对象

C++, Boost: How to store objects of an abstract type in a map container

本文关键字:抽象 存储 抽象类 类型 对象 Boost 地图 C++      更新时间:2023-10-16

我正在尝试使用地图容器来保存形状并将这些形状与ID号匹配。

到目前为止,我一直使用 STL 容器来保存和内存管理我的对象。 所以我会使用这些类型的容器:

std::map<int, Square> squares;
std::map<int, Triangle> triangles;
std::map<int, Circle> circles;

但是我想有一个地图来保存"形状",这是正方形、三角形和圆形的抽象基类。 因此,为了实现这一点,我仍然会将可实现的派生类对象存储在它们自己的映射中,然后使用另一个映射:

std::map<int, Shape*> shapes;

以存储指向存储在其他地图中的对象的指针。

不过,这似乎非常混乱,我宁愿将所有对象存储在一个拥有并内存管理所包含对象的多态映射中。

在阅读了一些关于Boost ptr_map的信息后,我希望这就是解决方案。 但似乎基类需要在尝试使用时实现:

boost::ptr_map<int,Shape> shapes;

我收到错误:"错误:无法分配抽象类型'形状'的对象"

我必须使基类可实现吗? 那会有点黑客,所以如果有这样的方法,我宁愿正确地做到这一点。

关于如何做到这一点,我的下一个最佳猜测是使用容器,例如:

std::map<int, boost::shared_ptr<Shape> > shapes;

这似乎是一个直截了当的目标,但由于我遇到了如此困难,我怀疑我正在尝试做一些我不应该做的事情。 因此,任何关于我可能出错的建议都非常感谢。

谢谢。

ptr_map<int, Shape>似乎是

要走的路,甚至可以与抽象基类型一起使用(请参阅此处的示例)。我想您获得的错误来自使用operator[].实际上,就像在std::map中一样,如果键尚未在映射中,则operator[]返回默认构造的值。在这种情况下,它无法构造值,因为Shape是抽象的,因此编译器错误。

因此,您可以使用ptr_map但不能使用索引运算符。插入时,使用 insert ,查找键时,使用 find

您的基类不需要实现。请参阅此处的示例:http://www.boost.org/doc/libs/1_49_0/libs/ptr_container/doc/tutorial.html#associative-containers那里的动物确实有抽象的功能!事实上,这是 ptr 容器的主要用途之一。您的错误可能是在其他地方引起的,您需要发布更多代码。

也:

不过,这似乎非常混乱,我宁愿将所有对象存储在一个拥有并内存管理所包含对象的多态映射中。

我不认为是。实际上,永远不要"丢失"实际对象的类型是有益的,以防以后需要它。例如,如果您想为所有三角形做一些事情,而不是所有其他形状,这将派上用场。

缺点当然是你需要保持所有映射同步,但这很容易解决:将这 4 个映射(最好没有其他数据成员!)粘贴到类的私有部分,并为不同类型的实现 3 个重载,并始终将它们插入到强类型的"拥有"映射中,并使用多态指针插入到映射中。我将非常轻松地将它们保持在一个小类界面后面的同步。只是不要尝试将其作为更大事物的非结构化部分来做,否则代码将开始看起来很混乱。