2015-07-10 21 views
3

我從QGraphicsItem類派生並繪製一些自定義形狀。這些多個形狀然後被添加到QGraphicsScene刪除和釋放QGraphicsItem類派生對象

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,正確的方法是使用delete操作上a,而不是任何的基類層次結構中的對象是否正確?

而且virtual destructors的使用與所有這一切有關嗎?

+0

請注意,您的刪除代碼可能非常危險,因爲如果您同時選擇了父項和子項,並且您刪除了父項,那麼該子項也將被刪除(因此您的刪除項將構成雙重刪除) – peppe

回答

2

QGraphicsItemvirtual destructor。因此,如果您致電delete item;,其中itemQGraphicsItem類型的指針,則將首先調用所有派生類的析構函數。要測試這個,只需實現StairCurve類的析構函數並查看它是否被調用。