我想使用QQueue来存储我的类的对象。该类的成员是指向QPoints的指针。我将类的对象存储在QQueue中并检索它。
#include <QQueue>
#include <QPoint>
#include <QDebug>
class Foo {
public:
Foo(int x, int y);
~Foo();
QPoint bar;
QPoint* baz;
//Q_DISABLE_COPY(Foo) // not sure whether I need this
};
Foo::Foo(int x, int y): bar(x, y) {
baz = new QPoint(x, y);
}
Foo::~Foo() {
delete this->baz;
}
int main(void) {
QQueue<Foo> queue;
Foo a(5, 6);
qDebug() << "a.bar.x()=" << a.bar.x() << ", a.baz->x()=" << a.baz->x();
queue.enqueue(a);
Foo b = queue.dequeue();
qDebug() << "b.bar.x()=" << b.bar.x() << ", b.baz->x()=" << b.baz->x();
return 0;
}
输出:
a.bar.x()= 5 , a.baz->x()= 5
b.bar.x()= 5 , b.baz->x()= 0
09:46:59: The program has unexpectedly finished.
如果我在析构函数中注释掉delete this->baz;
,我会得到我期望的结果:
a.bar.x()= 5 , a.baz->x()= 5
b.bar.x()= 5 , b.baz->x()= 5
有人可以解释这是怎么回事吗?在我看来,对Foo的破坏者正在被早期召集。谢谢。
答案 0 :(得分:1)
Read about "The rule of three/five/zero"。
基本上默认的复制构造函数在您的情况下无效,并且在将Bar
添加到queue
时使用(按值传递)。
结果,有两个Bar
对象,其中baz
指向相同的QPoint
。当一个对象死亡时,没有什么不好的事情发生,但是当复制死亡时,代码尝试释放已经释放的东西。这会导致崩溃。
答案 1 :(得分:0)
QQueue
存储所添加对象的副本。因此,在此行调用了Foo b = queue.dequeue();
的析构函数Foo
。您可以在调试器中确保这一点。将断点添加到Foo
析构函数并进行调试。