Разве std::unique_ptr::get
не противоречит цели иметь unique_ptr в первую очередь? Я ожидал, что эта функция изменит свое состояние, чтобы она больше не содержала указателя. Есть ли действительно полезное использование std::unique_ptr::get?
в чем смысл std::unique_ptr::get
Ответы (6)
Вы используете его каждый раз, когда вам нужно передать необработанный указатель, скажем, на функцию C:
std::unique_ptr<char[]> buffer( new char[1024] );
// ... fill the buffer
int rc = ::write( fd, buffer.get(), len );
std::unique_ptr
безопасно обеспечивает уникальную семантику владения. Однако это не исключает необходимости в указателях не принадлежащих. std::shared_ptr
имеет аналог, не являющийся владельцем, std::weak_ptr
. Необработанные указатели работают как std::unique_ptr
, не владеющие аналогом.
Правило, которому я обычно следую, таково: если вызываемый объект не возится со временем жизни/владением, не передавайте ему умный указатель; скорее, передайте необработанную ссылку C++ (предпочтительно) или необработанный указатель. Я считаю, что гораздо чище и гибче отделить заботу о владении от использования.
Когда у вас связаны руки и вам нужно передать указатель на что-то, p.get()
читается лучше, чем &*p
.
Существует функция, которая изменяет состояние, так что unique_ptr
больше не содержит указатель, и эта функция называется release
. Это в основном полезно для передачи владения другим интеллектуальным указателям, которые не обеспечивают прямое построение из unique_ptr
. Любое другое использование рискует привести к утечке ресурса.
&*
, вероятно, теоретически быстрее, поскольку у него нет гарантии предсказуемости .get()
, но впоследствии он практически более опасен, поскольку это может привести к неопределенному поведению.
- person Fake Code Monkey Rashid; 23.09.2020
У Херба Саттера есть хорошее объяснение (около 3:40) https://www.youtube.com/watch?v=JfmTagWcqoE
Основное преимущество состоит в том, что уникальный указатель отслеживает, сколько других ссылок существует на этот указатель. Вы работаете только с уникальным указателем, когда работаете с владением. Когда вы хотите что-то сделать с данными с помощью этого указателя, вы передаете необработанный указатель.
std::unique_ptr
не отслеживает, сколько ссылок есть на указатель. Они уникальны, поэтому ссылка ровно одна. Если вам нужен подсчет ссылок, std::shared_ptr
— это то, что вам нужно.
- person Kai Petzke; 21.07.2020
Существует очевидная ситуация, когда вам нужно вызвать C API или плохо спроектированный C++ API.
foo(*something)
, но я думаю, что это лучший дизайн, чем использование там указателей, потому что он лучше защищает от ошибок функционального контракта, не накладывая ограничений на тип указателя.
- person Sebastian Mach; 29.05.2012
std::addressof(*p)
. Нет необходимости делать вид, что базового указателя здесь нет. - person Luc Danton   schedule 29.05.2012