#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
, и может сделать недействительным итератор прошедшего конца.