#c #arrays #vector
#c #массивы #вектор
Вопрос:
Почему вызывается деструктор объекта, когда он выходит за пределы области видимости и когда он находится в векторе? Например :
std::vector<Foo> vec;
for (i=10; i<10; i )
{
Foo object(i);
vec.push_back(object);
}
Вызывается ли деструктор объекта, потому что он каждый раз выходит за пределы области видимости? Могу ли я заставить его работать без указателей или shared_pointers?
Комментарии:
1. Да; используйте
emplace_back
и создавайтеFoo
на месте.2. То, что заканчивается в векторе, является копией
object
, а неobject
самим собой.object
уничтожается при выходе из области видимости; его копия продолжает жить внутри вектора. Из вашего вопроса неясно, почему вы считаете это проблемой. Какую актуальную проблему, если таковая имеется, вы пытаетесь решить?3. Я был сбит с толку и подумал, что вектор принял указатель на объект, поскольку функция push_back принимает объект по ссылке. Спасибо.
4. Ссылка не является указателем (если мы не говорим о том, как компиляторы реализуют ссылки, но это не так). Ссылка — это, по сути, другое имя для объекта, на который ссылается объект, и часто используется при передаче объектов. Поскольку ваш вектор хранит
Foo
, а неFooamp;
нет, он будет использовать эту ссылку для копирования, создает свою собственнуюobject
, после чего ссылается на то, что сказал @Igor выше.5. Спасибо. Хотя я знаю, что ссылка не является указателем и что нельзя создавать массивы или ссылки.
Ответ №1:
- push_back помещает копию объекта в вектор
- объект фактически будет уничтожен, но копия сохранится в векторе
- Если вы хотите поместить точное содержимое объекта в вектор и заставить код работать, тогда используйте конструктор перемещения
Комментарии:
1. Итак, если я использую конструктор перемещения, объект не разрушается?
2. он будет уничтожен, но его содержимое будет перенесено в вектор, копирование выполнено не будет. это более эффективно
3. Хорошо, проблема в том, что в моем деструкторе объектов он уничтожает элементы в других объектах, поэтому я не хочу, чтобы он уничтожал эти элементы.
4. Мне уже некоторое время не нужно было использовать деструктор в таких случаях. Что это за элементы? Динамическое распределение? Затем попробуйте удалить его и использовать
shared_ptr
.5. Я не видел весь ваш код. попробуйте переместить и скажите мне. Он сохраняет содержимое объекта. Если нет, вам нужно прислать мне еще немного кода или отредактировать его.
Ответ №2:
object
исчезнет за пределами этой области видимости, это правильно. Нет, vector
не влияет и не мог повлиять на его время жизни. push_back
фактически копирует object
в vector
. Чтобы избежать этого, вы можете использовать C 11, emplace_back
который позволяет создавать Foo
на месте:
vec.emplace_back(i);
Эта тестовая программа подтверждает, что копирование, перемещение или дополнительное уничтожение не выполняется.
Constructing A
End of vec's scope
Destructing A
Комментарии:
1. Это все равно создает временный объект
Foo
, затем копирует его в вектор, а затем сразу уничтожает. Конечный результат точно такой же, как в исходном коде (за исключением того, что он использует конструктор по умолчаниюFoo
, тогда как в оригинале используется конструктор, принимающийint
). Вы, вероятно, имели в видуvec.emplace_back(i);
илиvec.emplace_back();
— это создает один-единственный экземплярFoo
на месте (с использованием однопараметрического конструктора или конструктора по умолчанию, соответственно).2. Правильно, я запутался. Я понял это позже, когда экспериментировал с Coliru. push_back и emplace_back в этом случае не сильно отличаются : coliru.stacked-crooked.com/a/b2894b7f4b2a8367
3. Опять же — чтобы увидеть разницу, сделайте это
vec.emplace_back()
4. Я думаю, что ваш ответ подходит мне лучше всего, потому что деструктор моего объекта является дорогостоящим, поэтому лучше создать только один объект.
5. о, я пропустил суть и не знал, как должен был использоваться emplace_back. я отредактирую свой ответ соответственно этому. Спасибо!
Ответ №3:
Это должно сработать
std::vector<Foo> vec;
for (i=10; i<10; i )
{
vec.emplace_back(i);
}
Комментарии:
1. вы должны удалить
foo object(i);
2. Это следует удалить