QGraphicsItems只能在堆上创建?

时间:2015-10-26 14:52:04

标签: c++ qt qgraphicsview qgraphicsscene

在QMainWindow的构造函数中......

在堆上创建一个新的圆圈并传递给场景,圆圈显示出来,每一个都在工作:

    QGraphicsScene * scene = new QGraphicsScene(this);
    CustomGraphicsView * view = new CustomGraphicsView(scene,this);

    QGraphicsEllipseItem * ellipse = new QGraphicsEllipseItem (100,100,30,30);
    ellipse->setPen(QPen(Qt::green,10));

    scene->addItem(ellipse);

现在我们在堆栈上创建圆圈并通过引用传递它。但这次cricle永远不会出现:

QGraphicsScene * scene = new QGraphicsScene(this);
CustomGraphicsView * view = new CustomGraphicsView(scene,this);

QGraphicsEllipseItem ellipse(100,100,30,30);
ellipse.setPen(QPen(Qt::green,10));

scene->addItem(&ellipse);

我猜它会在它出现之前被摧毁。但我不明白为什么?为什么这不起作用,这种行为背后的规则是什么?

2 个答案:

答案 0 :(得分:1)

来自http://doc.qt.io/qt-4.8/qgraphicsscene.html#addItem

  

将项目及其所有儿童添加或移动到此场景。此场景取得物品的所有权。

如果项目在堆栈上创建,则QGraphicsScene无法获得项目的所有权。这意味着必须在堆上创建项目。

答案 1 :(得分:0)

QGraphicsEllipseItem * ellipse = new QGraphicsEllipseItem (100,100,30,30);
ellipse->setPen(QPen(Qt::green,10));

scene->addItem(ellipse);

这是有效的,因为scene对象负责delete您通过new分配的对象。在Qt框架深处的某个地方,将会有一个调用:

delete item;

现在使用此代码:

QGraphicsEllipseItem ellipse(100,100,30,30);
ellipse.setPen(QPen(Qt::green,10));

scene->addItem(&ellipse);

考虑一下会发生什么。 delete item;仍然存在,但它不仅应用于指向本地对象的指针,而且(可能取决于程序流)也应用于指向不再存在的对象的指针。执行delete的代码根本不知道该对象是通过new 而不是创建的。

任何多次销毁对象的尝试都是未定义的行为,就像尝试使用已经被销毁的对象一样。你的问题是一个很好的例子,说明为什么传递指向本地对象的指针应该被视为一种特别危险的行为,需要格外小心。

顺便说一下:

  

但这次cricle永远不会出现:

这只是巧合。未定义的行为意味着一切都会发生。