QGraphicsItem只能在堆上创建?

QGraphicsItems can only be created on the heap?

在 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);

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

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

Adds or moves the item and all its childen to this scene. This scene takes ownership of the item.

A QGraphicsScene 无法取得在堆栈上创建的项目的所有权。这意味着必须在堆上创建项目。

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

scene->addItem(ellipse);

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

delete item;

现在使用此代码:

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

scene->addItem(&ellipse);

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

创建的

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

顺便说一句:

But this time the cricle will never shows up:

纯属巧合。未定义的行为意味着一切皆有可能。