Results 1 to 14 of 14

Thread: Destructor overriding

  1. #1
    Join Date
    Feb 2013
    Posts
    9
    Qt products
    Qt4 Qt5 Qt/Embedded Qt Jambi
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Destructor overriding

    I examined the Diagram Scene Example and faced this code:
    Qt Code:
    1. void DiagramItem::removeArrows()
    2. {
    3. foreach (Arrow *arrow, arrows) {
    4. arrow->startItem()->removeArrow(arrow);
    5. arrow->endItem()->removeArrow(arrow);
    6. scene()->removeItem(arrow);
    7. delete arrow;
    8. }
    9. }
    To copy to clipboard, switch view to plain text mode 

    Where Arrow is:
    Qt Code:
    1. class Arrow : public QGraphicsLineItem
    To copy to clipboard, switch view to plain text mode 
    My question is, whether it is better to implement DiagramItem::removeArrows() method that way instead of overriding the Arrow's destructor:
    Qt Code:
    1. Arrow::~Arrow() //Virtual destructor
    2. {
    3. startItem()->removeArrow(this);
    4. endItem()->removeArrow(this);
    5.  
    6. }
    To copy to clipboard, switch view to plain text mode 

    Then DiagramItem::removeArrows() would look like:
    Qt Code:
    1. void DiagramItem::removeArrows()
    2. {
    3. foreach (Arrow *arrow, arrows) {
    4. scene()->removeItem(this);
    5. delete arrow;
    6. }
    7. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by Daylight; 28th February 2013 at 17:09.

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Destructor overriding

    As long as the method is not virtual -- yes.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Feb 2013
    Posts
    9
    Qt products
    Qt4 Qt5 Qt/Embedded Qt Jambi
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Destructor overriding

    Quote Originally Posted by wysota View Post
    As long as the method is not virtual -- yes.
    Why? It seems to me that destructor overriding might prevent potential code duplication if one would need to delete arrows in other places. It will also prevent from potential repeated deletion, if one deleted an arrow, but forgot to clean the pointers in endItem() startItem() and objects. Cleaning of the arrow pointers in outer objects must occur every time the arrow is deleted, so why not implement it in destructor?
    Overriding of destructor will allow to make Arrow::stratItem() and Arrow::endItem() methods private.
    Last edited by Daylight; 28th February 2013 at 16:57.

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Destructor overriding

    Quote Originally Posted by Daylight View Post
    Why?
    Why what?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Feb 2013
    Posts
    9
    Qt products
    Qt4 Qt5 Qt/Embedded Qt Jambi
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Destructor overriding

    Why is it better to implement separate DiagramItem::removeArrows() function with explicit pointer cleaning outside of Arrow object (like it is done in Diagram Scene Example)?
    Last edited by Daylight; 28th February 2013 at 17:09.

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Destructor overriding

    I didn't say it was better or worse. Both are acceptable solutions as far as they serve your goal. As long as you don't call a virtual method on oneself from its own destructor, everything is fine. Consider the fact that QGraphicsItem has its own destructor that will remove all its children and remove itself from the scene. It will not detach it from items that are not part of its parent-child relationship. Your destructor has this problem that it an arrow is not attached to an item (e.g. the item is destroyed before the arrow is removed), your program will crash. In the original code an arrow can function without an object attached to it since it is a "stupid" object that doesn't care about its environment.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. #7
    Join Date
    Feb 2013
    Posts
    9
    Qt products
    Qt4 Qt5 Qt/Embedded Qt Jambi
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Destructor overriding

    Quote Originally Posted by wysota View Post
    I didn't say it was better or worse. Both are acceptable solutions as far as they serve your goal. As long as you don't call a virtual method on oneself from its own destructor, everything is fine. Consider the fact that QGraphicsItem has its own destructor that will remove all its children and remove itself from the scene. It will not detach it from items that are not part of its parent-child relationship. Your destructor has this problem that it an arrow is not attached to an item (e.g. the item is destroyed before the arrow is removed), your program will crash. In the original code an arrow can function without an object attached to it since it is a "stupid" object that doesn't care about its environment.
    If the item is destroyed before the arrow is removed, the program will crash anyway, because the other item will try to access destroyed item via Arrow::start/endItem(). It is not possible, though, because every item stores the list of attached arrows and removes them before destruction.
    But, youre right, it seems it is better to make arrow a child of this->startItem(), this is more safe. Example's objects architecture seems a bit odd to me...
    Last edited by Daylight; 28th February 2013 at 17:57.

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Destructor overriding

    No, making the arrow a child of any item is not a good idea. Think what happens if you try to rotate or scale such item.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  9. #9
    Join Date
    Feb 2013
    Posts
    9
    Qt products
    Qt4 Qt5 Qt/Embedded Qt Jambi
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Destructor overriding

    Quote Originally Posted by wysota View Post
    No, making the arrow a child of any item is not a good idea. Think what happens if you try to rotate or scale such item.
    It should be fine. Arrows rendering is treated in Arrow:: paint(), so it should be ok.

  10. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Destructor overriding

    It will not be fine. The arrow will be rotated or scaled as well.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  11. #11
    Join Date
    Feb 2013
    Posts
    9
    Qt products
    Qt4 Qt5 Qt/Embedded Qt Jambi
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Destructor overriding

    Quote Originally Posted by wysota View Post
    It will not be fine. The arrow will be rotated or scaled as well.
    Why would it be? It will be repainted (correctly) each time the parent object is changed. The painting is done with respect to start/endItem() coordinates using the mapFromItem(myStart/endItem, 0, 0).

  12. #12
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Destructor overriding

    Quote Originally Posted by Daylight View Post
    The painting is done with respect to start/endItem() coordinates using the mapFromItem(myStart/endItem, 0, 0).
    Coordinates of the items will not change if they are rotated or scaled. If you counter that then you counter everything GraphicsView stands for. The arrow simply can't be a child of an item if it is supposed to be independent of the item. Besides it is attached to two items and it can't have two parents.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  13. #13
    Join Date
    Feb 2013
    Posts
    9
    Qt products
    Qt4 Qt5 Qt/Embedded Qt Jambi
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Destructor overriding

    Quote Originally Posted by wysota View Post
    Coordinates of the items will not change if they are rotated or scaled. If you counter that then you counter everything GraphicsView stands for. The arrow simply can't be a child of an item if it is supposed to be independent of the item. Besides it is attached to two items and it can't have two parents.
    From the logical point of view, arrow may be a child of an item it starts from. It is not completely independent, it should always be connected to two items. Arrows can not be moved directly, only by moving start/end Items.
    This is from the example:
    Qt Code:
    1. void Arrow::updatePosition()
    2. {
    3. QLineF line(mapFromItem(myStartItem, 0, 0), mapFromItem(myEndItem, 0, 0));
    4. setLine(line);
    5. }
    To copy to clipboard, switch view to plain text mode 

  14. #14
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Destructor overriding

    Ok, here is a small framework. Try completing it so that it works properly.

    Qt Code:
    1. #include <QtGui>
    2. #if QT_VERSION >= 0x050000
    3. #include <QtWidgets>
    4. #endif
    5.  
    6. class Arrow;
    7.  
    8. class RotatingItem : public QGraphicsRectItem {
    9. public:
    10. RotatingItem(const QRectF &rect, QGraphicsItem *parent = 0) : QGraphicsRectItem(rect, parent){
    11. setFlag(ItemSendsGeometryChanges, true);
    12.  
    13. }
    14. protected:
    15. void wheelEvent(QGraphicsSceneWheelEvent *event) {
    16. if(event->modifiers() & Qt::ShiftModifier) {
    17. setScale(scale()* (event->delta() > 0 ? 1.1 : 0.9));
    18. } else {
    19. setRotation(rotation()+(event->delta()/15.0));
    20.  
    21. }
    22. }
    23. QVariant itemChange(GraphicsItemChange change, const QVariant &value) {
    24. if(change == ItemPositionHasChanged && scene()) {
    25. foreach(Arrow *a, m_arrowStartsHere) updateStartArrowPosition(a);
    26. foreach(Arrow *a, m_arrowEndsHere) updateEndArrowPosition(a);
    27.  
    28. }
    29. return QGraphicsRectItem::itemChange(change, value);
    30. }
    31. void updateStartArrowPosition(Arrow *);
    32.  
    33. void updateEndArrowPosition(Arrow *);
    34.  
    35. private:
    36. QList<Arrow*> m_arrowStartsHere;
    37. QList<Arrow*> m_arrowEndsHere;
    38.  
    39.  
    40. friend class Arrow;
    41. };
    42.  
    43. class Arrow : public QGraphicsLineItem {
    44. public:
    45. Arrow(RotatingItem *st, RotatingItem *en) :QGraphicsLineItem(st) {
    46. startItem = st;
    47. endItem = en;
    48. QPointF end = mapFromItem(endItem, endItem->boundingRect().center());
    49. setLine(0,0, end.x(), end.y());
    50. startItem->m_arrowStartsHere << this;
    51. endItem->m_arrowEndsHere << this;
    52.  
    53. m_text = new QGraphicsSimpleTextItem(this);
    54. QFont f;
    55. f.setPointSize(8);
    56. m_text->setFont(f);
    57. updateArrowContent();
    58. }
    59. RotatingItem *start() const { return startItem; }
    60. RotatingItem *end() const { return endItem; }
    61. void updateArrowContent() {
    62. m_text->setPos(line().pointAt(0.5));
    63. m_text->setText(QString::number(line().length()));
    64. }
    65.  
    66. protected:
    67. RotatingItem *startItem, *endItem;
    68. };
    69.  
    70. class GraphicsView : public QGraphicsView {
    71. public:
    72. GraphicsView(QWidget *parent = 0) : QGraphicsView(parent){}
    73. protected:
    74. void paintEvent(QPaintEvent *event) {
    75. QGraphicsView::paintEvent(event);
    76. QPainter p(viewport());
    77. p.drawText(viewport()->rect().adjusted(10,10,-10,-10), "Drag item to move\nWheel to rotate\nSHIFT+wheel to scale");
    78. }
    79. };
    80.  
    81. int main(int argc, char **argv) {
    82. QApplication app(argc, argv);
    83. GraphicsView view;
    84. view.setScene(&scene);
    85. RotatingItem *item1 = new RotatingItem(QRect(-50, -50, 100, 100));
    86. RotatingItem *item2 = new RotatingItem(QRect(-50, -50, 100, 100));
    87. scene.addItem(item1);
    88. scene.addItem(item2);
    89. item1->setPos(100,100);
    90. item2->setPos(200,200);
    91. item1->setFlag(QGraphicsItem::ItemIsMovable);
    92. item2->setFlag(QGraphicsItem::ItemIsMovable);
    93. item1->setBrush(Qt::red);
    94. item2->setBrush(Qt::yellow);
    95. Arrow *arr = new Arrow(item1, item2);
    96. QPen p;
    97. p.setWidth(4);
    98. p.setColor(Qt::blue);
    99. arr->setPen(p);
    100. item1->setZValue(10);
    101. item2->setZValue(0);
    102. arr->setZValue(10);
    103. view.setRenderHint(QPainter::Antialiasing);
    104. view.resize(400,400);
    105. view.show();
    106. return app.exec();
    107. }
    108.  
    109.  
    110. void RotatingItem::updateStartArrowPosition(Arrow *arrow)
    111. {
    112. QLineF l = arrow->line();
    113. l.setP2(arrow->end()->mapToItem(arrow, arrow->end()->boundingRect().center()));
    114. arrow->setLine(l);
    115. arrow->updateArrowContent();
    116. }
    117.  
    118. void RotatingItem::updateEndArrowPosition(Arrow *arrow)
    119. {
    120. QLineF l = arrow->line();
    121. l.setP2(mapToItem(arrow, boundingRect().center()));
    122. arrow->setLine(l);
    123. arrow->updateArrowContent();
    124. }
    To copy to clipboard, switch view to plain text mode 

    Problems to solve:
    1. make sure the line sticks to its items when rotation and scale of any of them changes
    2. make sure the length reported by the line is consistent when the line's starting item is scaled
    3. make sure the width of the line doesn't depend on the scale of the red item or that it depends on the scale of both the red and the yellow item (the choice is yours)
    4. make it possible for the yellow item to be over the red item (in terms of Z-value) and the line to be on top of the yellow item (in other words make it possible so that the line is always on top of the other items regardless of the stacking order of the items themselves)
    Last edited by wysota; 1st March 2013 at 12:25.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


Similar Threads

  1. Overriding Proxies
    By jdgrant in forum Qt Programming
    Replies: 0
    Last Post: 25th November 2011, 02:23
  2. Overriding global new
    By branko in forum Qt Programming
    Replies: 2
    Last Post: 19th October 2010, 17:10
  3. overriding QListWidget advice
    By codebehind in forum Qt Programming
    Replies: 3
    Last Post: 28th September 2010, 23:39
  4. Overriding drawRubberBand()
    By andrew.nguyen in forum Qwt
    Replies: 3
    Last Post: 21st April 2010, 07:58
  5. Overriding shortcuts for QGraphicsItems
    By pherthyl in forum Qt Programming
    Replies: 3
    Last Post: 16th May 2008, 23:47

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.