Правильно ли этот код?
auto v = make_unique<int>(12);
v.release(); // is this possible?
Является ли он эквивалентным delete
исходного указателя?
Правильно ли этот код?
auto v = make_unique<int>(12);
v.release(); // is this possible?
Является ли он эквивалентным delete
исходного указателя?
Нет, код вызывает утечку памяти. release
используется для освобождения права собственности на управляемый объект без его удаления:
auto v = make_unique<int>(12); // manages the object
int * raw = v.release(); // pointer to no-longer-managed object
delete raw; // needs manual deletion
Не делайте этого, если у вас нет веской причины жонглировать необработанной памятью без защитной сетки.
Чтобы удалить объект, используйте reset
.
auto v = make_unique<int>(12); // manages the object
v.reset(); // delete the object, leaving v empty
Правильно ли этот код?
Нет. Используйте std::unique_ptr<>::reset()
для удаления внутреннего необработанного указателя:
auto v = std::make_unique<int>(12);
v.reset(); // deletes the raw pointer
После этого std::unique_ptr<>::get()
вернет nullptr
(если вы не указали параметр nullptr
std::unique_ptr<>::reset()
).
Правильно ли этот код?
Нет! Произойдет утечка.
release()
просто позвоните вызывающему коду повторно захватить память, хранящуюся в unique_ptr
, пока она не будет вызвана. Если вы не назначили указатель, возвращаемый release()
, у вас будет только утечка.
Явное удаление для unique_ptr
будет reset()
. Но помните, что unique_ptr
существует, так что вам не нужно напрямую управлять памятью, которую они хранят. То есть вы должны знать, что unique_ptr
безопасно удалит свой основной необработанный указатель, как только он выйдет из области видимости.
Поэтому у вас должна быть очень веская причина для ручного управления памятью в автоматическом объекте управления памятью.
release
будет просачивать ваш необработанный указатель, так как вы его не присваиваете.
Он предназначен для использования для чего-то вроде
int* x = v.release();
Это означает, что v
больше не управляет временем жизни этого указателя, он делегирует собственность raw pointer на x
. Если вы просто release
не присваиваете ничего, вы пропустите исходный указатель.
для произвольных типов может быть немного сложно:
unique_ptr<Foo> v = get_me_some_foo(); // manages the object
Foo * raw = v.release(); // pointer to no-longer-managed object
delete raw;
почти правильно.
unique_ptr<Foo> v = get_me_some_foo(); // manages the object
Foo * ptr = v.release(); // pointer to no-longer-managed object
v.get_deleter() ( ptr );
этот был бы правильным во всех ситуациях; может быть пользовательский делетер, определенный по типу Foo, но использование делетера, возвращаемого объектом unique_ptr, хорошо для всех случаев.