繁体   English   中英

将具有继承同一类的不同类型的对象存储在容器中

[英]Store objects with different types that inherit the same class in a container

我有以下课程:

class ActivityItem : public QGraphicsItem;
class DeadTimeItem : public QGraphicsItem;

我现在需要将ActivityItemDeadTimeItem类型的两个对象存储在同一容器中,以便可以一起使用它们。

我尝试了什么?

我尝试创建一个存储QGraphicsItem类型的QVector ,但结果是它不能存储抽象类类型。 我该怎么办?

我的计划

我的计划是将这些元素存储到类timeline QVector<T>成员中,因为它们将创建时间轴。 例如:

class timeline : public QGraphicsScene // is this a good idea? to inherit QGraphicsScene?
{
private:
    QVector<QGraphicsItem*> items;
    int left_offset; // this is for putting the items next to each other
public:
    timeline();
    void add_item( QGraphicsItem *item );
    ~timeline();
}

我的时间轴应如下图所示:

在此处输入图片说明

因此,当用户调用add_item()方法时,

Timeline *timeline;
timeline->add_item( new ActivityItem( /* parameters */ ) ); // timeline->left_offset += 150;
timeline->add_item( new DeadTimeItem( /* parameters */ ) ); // timeline->left_offset += 100;

left_offset随插入项目的类型而增加。

我知道我的帖子很长,但是请完整阅读,因为我真的需要您的帮助! 谢谢!

正如您已经猜到的,我正在使用Qt。 如果确实需要,我也可以使用boost。

您不能创建一个幸运的抽象类的实例,因为尝试将派生类分配给基类会以其他有趣的方式引起切片或行为异常。

由于上述限制,没有用于base的标准容器可以存储派生对象。 您可以通过使用指向基础的指针(原始(非所有权)指针或某些智能指针类型)来规避此限制。

使用标准库的答案将类似于:

std::vector<std::shared_pointer<QGraphicsItem>> v;

使用QT类:

QVector<QSharedPointer<QGraphicsItem>> qv;

假设

  • QGraphicsItem对象是同一场景的一部分,并且具有父级
  • 该列表与场景紧密相关(拥有场景的同一类的成员变量,或场景子类的成员变量)。

然后,您应该使用以下代码:

    QList<QGraphicsItem*> items; // or QVector or std::list, nearly same

这些是原始指针,从列表中删除时它们不会自动删除对象,而在删除项目时也不会得到通知。 我仍然不知道可以与QGraphicsItem一起使用的智能指针类型,因此必须使用原始指针。 因此,如果您还需要动态删除项目,请继续阅读:


首先,在删除项目时,还需要从列表中删除指针,以免指针悬空。 举例来说,您可能想使用类似QList::indexOf()QList::removeAt()方法的方法(此外, 如果删除非常普遍并且列表中有很多项目,则可能需要重新考虑方法,因为从大型阵列中删除速度很慢)。 您需要注意,如果没有机会从列表中将其删除,则该项目不会被某些Qt代码删除。

如果您可能在列表中有项目,而列表中有他们的孩子,那么事情会变得更加复杂。 如果您只是删除一个项目,它将删除它的子项,因此,如果您的列表中有指向这些子项的指针,并且您的列表最终将带有指向那些子项的悬挂指针。 因此,您需要非常小心地删除。 我可以想到的解决方法至少有3种(在您自己的代码中递归删除,从项目析构函数的列表中删除,使用事件过滤器捕获项目删除),因此,在这种情况下,我可以扩大答案发生在您的代码中。

最后说明:删除整个场景时,它将删除其所有子级。 您在这里要做的只是确保列表中已删除项目的指针永远不会被使用,例如,只需清除列表即可。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM