删除和释放 QGraphicsItem 类派生对象

Posted

技术标签:

【中文标题】删除和释放 QGraphicsItem 类派生对象【英文标题】:Deleting and freeing QGraphicsItem class derived objects 【发布时间】:2015-07-10 06:43:28 【问题描述】:

我从QGraphicsItem 类派生并绘制了一些自定义形状。然后将这些多个形状添加到QGraphicsScene

class StairCurve : public QObject, public CurveShape, public QGraphicsItem

class BezierCurve: public QObject, public CurveShape, public QGraphicsItem

CurveShape 是一个类,它具有与这些曲线相关的一些公共属性,如 ID 等。它不是从其他任何东西派生的。不过它有一些pure virtual 功能。

为了从场景中删除所有贝塞尔曲线,我正在做这样的事情:

        QList<QGraphicsItem*> all = selectedItems();
        for (int i = 0; i < all.size(); i++)
        
            QGraphicsItem * item = all[i];

            if( NULL != item && (BezierCurve::Type == item->type()) )
            
                removeItem(item);
                delete item;
                item  = NULL;
            
       

QGraphicsItem * item = all[i]; 将返回一个指向我对象的基类部分的指针。所以对我来说调用 remove 看起来不错。该对象将不再是场景的一部分。

我担心在item 上调用delete 会调用基类的析构函数,对吗?我认为它不会从内存中删除完整的对象。做这样的事情会更有意义:

delete dynamic_cast<BezierCurve*>(item);

更正式地说,

Class A : public B, public C
Class B : public D

A *a;

要删除对象a,正确的方法是在a 上使用delete 运算符,而不是在层次结构中的任何基类对象上,对吗?

virtual destructors 的使用与这一切有什么关系吗?

【问题讨论】:

请注意,您的删除代码可能非常危险,就好像您同时选择了父母和孩子,并且您删除了父母,孩子也将被删除(因此您对它的删除将构成双重删除) 【参考方案1】:

QGraphicsItem 有一个virtual destructor。因此,如果您调用delete item;,其中itemQGraphicsItem 类型的指针,所有派生类的析构函数将首先被调用。为了测试这一点,只需实现StairCurve类的析构函数,看看它是否被调用。

【讨论】:

以上是关于删除和释放 QGraphicsItem 类派生对象的主要内容,如果未能解决你的问题,请参考以下文章

将鼠标事件从 QGraphicsItem 传递给 QGraphicsScene

生成一个派生类对象时,调用基类和派生类构造函数按啥次序

更改 boundingRect 后的 QGraphicsItem 位置

虚析构函数

面向对象总结

C ++从向量中删除指针会导致堆错误