Как я могу поставить в очередь и снять класс с членов указателя QPoint? - PullRequest
0 голосов
/ 08 апреля 2019

Я хотел бы использовать 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

Может ли кто-нибудь объяснить, что здесь происходит? Мне кажется, что деструктора Фу называют рано. Спасибо.

Ответы [ 2 ]

1 голос
/ 08 апреля 2019

Прочтите о «Правиле трех / пяти / нуля» .

По умолчанию конструктор копирования по умолчанию недопустим и используется при добавлении Bar вqueue (передача по значению).В результате есть два Bar объекта, где baz указывает на один и тот же QPoint.Когда один объект умирает, ничего плохого не происходит, но когда умирает копия, код пытается выпустить что-то, что уже было выпущено.Это приводит к сбою.

0 голосов
/ 08 апреля 2019

QQueue хранит копию добавленного объекта.Итак, в этой строке Foo b = queue.dequeue(); вызывается деструктор Foo.Вы можете убедиться в этом в отладчике.Добавьте точку останова к деструктору Foo и отладьте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...