C — Вызывается ли деструктор, когда вектор содержит объекты?

#destructor

#деструктор

Вопрос:

Если я динамически выделяю объекты класса внутри вектора, вызывается ли деструктор для каждого объекта, если я использую clear()?

Ответ №1:

Что именно вы подразумеваете под «динамически распределять»? Если вы используете vector<foo> , то все в порядке. Если вы вводите указатели через vector<foo*> , то деструкторы вызываться не будут, потому что указатели сами по себе не имеют деструкторов.

Однако обратите внимание, что в vector<foo> случае вы можете обнаружить, что ваши конструкторы и деструкторы вызываются намного чаще, чем вы ожидаете, например, при изменении размера вектора, потому что вектор будет использовать их при перемещении объектов в памяти, если это необходимо. Вы можете использовать Boost shared_ptr , чтобы обойти это, хотя это требует небольших затрат на доработку из-за учета количества ссылок.

Мой совет: используйте, vector<foo> если объекты дешевы для копирования и уничтожения, и vector<shared_ptr<foo> > если они дорогие или их трудно / невозможно скопировать. Никогда не используйте vector<foo*> , если вы специально не хотите избежать использования векторной ручки управления памятью, и только тогда будьте осторожны; это редко бывает хорошей идеей, ИМХО.

Комментарии:

1. Если вы используете перемещение объекта в контейнере; объект в контейнере остается, но не должен быть уничтожен. Что происходит тогда?

2. Оригинальный ответ был написан до того, как std::move() стал широко использоваться. Что произойдет, так это то, что объект все равно будет уничтожен. На самом деле это имеет место в общем случае, IIRC — ожидается, что объекты будут отслеживать, когда они были «перемещены», и заставят их деструкторы вести себя соответствующим образом. Единственная сложность заключается в том, что никто не должен смотреть на состояние элемента, перенесенного из, пока ему не будет присвоено новое значение или он не будет уничтожен.

Ответ №2:

Да, все они очищены должным образом.

По этой ссылке:

Все элементы вектора удаляются: вызываются их деструкторы, а затем они удаляются из векторного контейнера, оставляя контейнер размером 0.

[sequence.reqmts] Раздел готовящегося стандарта также разъясняет это:

a.clear() уничтожает все элементы в a , делает недействительными все ссылки, указатели и итераторы, ссылающиеся на элементы a , и может сделать недействительным итератор прошедшего конца.