【问题标题】:List of subclass objects reinterpreted as a list of base class objects? (C++11)子类对象列表重新解释为基类对象列表? (C++11)
【发布时间】:2017-03-22 17:50:28
【问题描述】:

我一直在使用一个提供多边形三角剖分的库。由于我试图将更多信息(一个 ID 和一堆方法)附加到它消耗的多边形和它返回的三角形上,我继承了它的内部多边形类 (Poly) 来创建我自己的多边形类 (PolyMine)。我有数百个多边形的列表,其中足够多的多边形进行迭代以进行任何转换都需要相当长的时间。我无法预先分配内存,因为我在运行时从 SVG 文件中消耗了未知数量的多边形。

定义如下:

class PolyMine : public Poly
{
public:
  void AddPoint(float _x, float _y);

private:
  int id
  // ...etc
}

我正在创建一个对象列表:

std::list<PolyMine> outlinePolygons;
std::list<PolyMine> resultTriangles;

并想在三角测量中使用它们:

Triangulate(&outlinePolygons, &resultTriangles);

但是,正如在 C++ 方面有更多经验的人可能已经看到的那样,这不起作用,因为 Triangulate 需要一个指向 Poly 列表的指针。现在,我的印象是,在这种情况下,程序会简单地“跳过”PolyMine 中不在Poly 中的部分,并使用该列表。

在尝试用谷歌搜索该问题后,除了 C# 解决方案之外,我没有提出任何建议。在这一点上,我假设我缺乏实际制定一个好的搜索查询的措辞。

我真的必须遍历列表才能将孩子重铸为他们的父类型吗?我缺少转换吗?这甚至不可能或不合理吗?任何提示表示赞赏。

【问题讨论】:

  • “我的印象是,在这种情况下,程序会简单地‘跳过’ PolyMine 中不在 Poly 中的部分”你错了。 list&lt;Poly&gt;list&lt;PolyMine&gt; 100% 不相关,编译器知道这一点。
  • @MooingDuck 我的困惑源于能够做到这一点的简单性:Poly a = b; 其中 b 是“PolyMine”。如果您愿意,它只是“降级”。感谢您的评论。
  • 我不确定这是否可行,但您可以尝试将指针列表传递给 Triangulate。这样您就可以将 PolyMine 对象存储在其中。可能值得更熟悉多态性。 std::list&lt;Poly *&gt; outlinePolygons; // Still fill it with PolyMine objects 那你可以试试把它传进去。再次不确定它是否会起作用,但值得一试
  • @picklechips Triangulate 是我无法编辑的库函数。如果没有“方便”的解决方案,我可能只需要迭代和转换每个项目。感谢您的评论。
  • 我了解,您不必编辑它。 Santiago Varela 刚刚发布了我所说的答案,看看那里。

标签: c++ list inheritance type-conversion


【解决方案1】:

在 C++ 中,您使用指针和动态内存进行泛化/继承。

您可以将列表设为 Poly 指针:

std::list<std::unique_ptr<Poly>> outlinePolygons;
std::list<std::unique_ptr<Poly>> resultTriangles;

Poly* childPoly = new PolyMine;
Poly* childPoly2 = new AnotherPoly;  // Another derived class from Poly
outlinePolygons.insert(childPoly);
outlinePolygons.insert(childPoly2);

通过这种方式,您将所有 Poly 引用存储到具体派生对象。

更新

知道Triangulate 函数签名是:

Triangulate(std::list<Poly> *inpolys, std::list<Poly> *outtris);

您的列表现在可以像这样使用智能指针进行实​​例化:

std::unique_ptr<std::list<Poly>> outlinePolygons = new std::list<Poly>;
std::unique_ptr<std::list<Poly>> resultTriangles = new std::list<Poly>;

Triangulate 现在可以工作了,但我预见会有问题,因为std::list&lt;Poly*&gt;std::list&lt;std:unique_ptr&lt;&lt;Poly&gt;&gt;std::list&lt;Poly&gt;* 不同,这是Triangulate 期望的两个参数。您将无法使用PolyMine 派生类对象填充列表std::list&lt;Poly&gt;*,除非您可以创建另一个采用Poly* 列表的函数:

Triangulate(std::list<Poly*> *inpolys, std::list<Poly*> *outtris); // A function with the same name but different parameter types is allowed in C++.

【讨论】:

  • 您还必须记住在使用完对象后删除这些对象。
  • 谢谢。 @GuillaumeRacicot 现在使用了 std::unique_ptr (智能指针),它消除了不得不释放(删除)内存的痛苦。
猜你喜欢
  • 1970-01-01
  • 2011-12-27
  • 1970-01-01
  • 1970-01-01
  • 2019-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多