Правильно ли этот код?
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, хорошо для всех случаев.