У меня есть следующий простой код, и я не нашел нить, где умные указатели используются для этого простого случая, а копировать объекты:Интеллектуальные указатели - unique_ptr для переменной в стеке выделяется
int main()
{
int i = 1;
std::unique_ptr<int> p1(&i);
*p1 = 2;
return 0;
}
Этот приводит к ошибке _BLOCK_TYPE_IS_INVALID
, когда указатель выходит из сферы видимости. Если я звоню p1.release()
, код работает нормально, и я не получаю эту ошибку. Я думал, что такие указатели достаточно умны, чтобы обращаться с оборванными указателями?
Альтернативой было бы, если бы я была копия I, которая не дает вышеуказанную ошибку:
std::unique_ptr<int> p1(new int(i));
Что такое преимущество использования смарт-указатели здесь, где я не хочу, чтобы выполнить локальный копировать?
Если бы я должен был использовать сырой указатель:
int i = 1;
int *p1 = &i;
*p1 = 2;
Я не получаю сообщение об ошибке, даже если я не код:
p1 = nullptr;
Благодарю вас обоих, это имеет смысл. Кроме того, почему я не могу просто p1 = nullptr, а не p1.release(). Я понимаю, что release() возвращает указатель на управляемый объект и освобождает право собственности. p1.reset() заменяет управляемый объект, поэтому имеет смысл, что это незаконно для переменной, присвоенной стеку. Но почему p1 = nullptr компилируется, но вызывает исключение? – c0der
Назначение 'unique_ptr' с [' = '] (http://www.cplusplus.com/reference/memory/unique_ptr/operator=/) в основном совпадает с вызовом [' reset'] (http: // www .cplusplus.com/reference/memory/unique_ptr/reset /) и уничтожает ранее сохраненный указатель. Использование ['release'] (http://www.cplusplus.com/reference/memory/unique_ptr/release/) оставляет владение указателем, не уничтожая его. – qxz
'p1 = nullptr' является назначением, p1 должен очистить свой указатель, а затем удерживать nullptr. Это то, что должен делать владелец. 'p1.release()' состоит в том, чтобы отдать свое «право собственности» и вернуть указатель на него другим, и больше не управлять, чтобы он не очистил его. –