C ++ std :: queue :: pop () вызывает деструктор. Что из типов указателей? - PullRequest
15 голосов
/ 05 января 2010

У меня есть std::queue, который обернут как шаблонный класс, чтобы создать потокобезопасную очередь. У меня есть две версии этого класса: одна, в которой хранятся типы значений, другая, в которой хранятся типы указателей.

Для типа указателя у меня возникают проблемы при удалении элементов очереди при уничтожении. Причина в том, что я не знаю, как безопасно удалить элементы из очереди.

Эта ссылка заявляет (бессмысленно, так что я полагаю, что на самом деле это НЕ СОСТОЯНИЕ), что единственный способ удалить элементы из очереди - вызвать pop(). Ссылка также говорит, что pop() вызывает деструктор для элемента.

Ну, это вызывает проблемы с моими типами указателей, потому что они могут указывать или не указывать на агрегаты. Если один из них указывает на агрегат, все они будут это делать, но поскольку оболочка является шаблонной, нет гарантии, с каким типом (агрегированным или неагрегированным) мы имеем дело.

Итак, когда pop() вызывает деструктор, что происходит? Как мне убедиться, что все удаляется и память освобождается правильно?

Наконец, мое решение использует более старую версию GCC для ARM9. Я не могу это контролировать. Я понимаю, что есть библиотеки, которые имеют интеллектуальные указатели и контейнеры, которые могут помочь здесь, но они для меня запрещены.

Ответы [ 3 ]

33 голосов
/ 05 января 2010

Указатели сами по себе на самом деле не имеют деструкторов, поэтому вызов pop() в очереди, содержащей указатель, не вызовет деструктор объекта, на который указывает указатель.

17 голосов
/ 05 января 2010

Интернет-источники стоят того, за что вы им платите - получите правильную ссылку, например Книга Йосуттиса . pop () не "вызывает деструктор" - он просто удаляет элемент из базового представления адаптера очереди (по умолчанию std :: deque), вызывая для него pop_front (). Если у извлекаемой вещи есть деструктор, она будет использоваться, когда извлеченный объект выходит из области видимости, но класс очереди не имеет к этому никакого отношения.

4 голосов
/ 05 января 2010

«Как я могу убедиться, что все удаляется и правильно освобождается память?»

Если вам абсолютно необходимо хранить указатели в своей очереди и вы хотите, чтобы они автоматически освобождались при редактировании pop, то вместо очереди указателей вам нужна очередь объектов, в которых хранится указатель и удали его в своем деструкторе. Например, вы можете использовать очередь shared_ptr. shared_ptr не входит в стандартную библиотеку, но она является частью TR1 и широко доступна.

В противном случае вызывающая сторона несет ответственность за удаление объекта:

T *off = q.front();
q.pop();
delete off;

Суть в том, что контейнеры с указателями на динамически размещаемые объекты немного неудобны. Если вы можете разработать свою программу так, чтобы контейнеры хранили копии ваших объектов, а не указатели на динамические объекты, то сделайте это. В противном случае вы несете ответственность за владение ресурсами, а не за контейнер. Контейнеры STL ничего не знают о владении, они просто копируют и уничтожают свои value_type. Копирование и уничтожение указателей никак не влияет на объекты, на которые они указывают.

...