std :: auto_ptr в std :: unique_ptr - PullRequest
       63

std :: auto_ptr в std :: unique_ptr

179 голосов
/ 10 августа 2010

С появлением нового стандарта (и частей, уже доступных в некоторых компиляторах), новый тип std::unique_ptr должен заменить std::auto_ptr.

Их использование точно совпадает (так что я могу выполнить глобальный поиск / замену в моем коде (не то, чтобы я это делал, но если бы я это сделал)) или я должен знать о некоторых различиях, которые не очевиднычитать документацию?

Также, если это прямая замена, зачем давать ему новое имя, а не просто улучшать std::auto_ptr?

Ответы [ 4 ]

210 голосов
/ 10 августа 2010

Вы не можете выполнить глобальный поиск / замену, потому что вы можете скопировать auto_ptr (с известными последствиями), но unique_ptr можно только переместить.Все, что выглядит как

std::auto_ptr<int> p(new int);
std::auto_ptr<int> p2 = p; 

, должно стать по крайней мере таким:

std::unique_ptr<int> p(new int);
std::unique_ptr<int> p2 = std::move(p);

Что касается других различий, unique_ptr может правильно обрабатывать массивы (это вызовет delete[],в то время как auto_ptr попытается вызвать delete.

87 голосов
/ 10 августа 2010

std::auto_ptr и std::unique_ptr в некоторых случаях несовместимы, а в других - снижение замены. Таким образом, не найти / заменить не достаточно хорошо. Однако после поиска / замены, работающего с ошибками компиляции, следует исправить все, кроме странных угловых случаев. Большинство ошибок компиляции потребует добавления std::move.

  • Переменная области действия функции:
    100% совместимость, если вы не передаете ее по значению другой функции.
  • Тип возврата:
    не на 100% совместим, но на 99% совместим не кажется неправильным.
  • Параметр функции по значению:
    100% совместимость с одним предупреждением, unique_ptr s должно быть передано через std::move вызов. Это просто, так как компилятор будет жаловаться, если вы не поймете это правильно.
  • Функциональный параметр по ссылке:
    100% совместимость.
  • Переменная члена класса:
    Этот хитрый. Семантика копирования std::auto_ptr зла. Если класс запрещает копирование, то std::unique_ptr является заменой. Однако, если вы попытались дать разумную семантику копирования классу, вам нужно изменить код обработки std::auto_ptr. Это просто, так как компилятор будет жаловаться, если вы не понимаете это правильно. Если вы разрешили копировать класс с std::auto_ptr членом без какого-либо специального кода, то позор вам и удача.

Таким образом, std::unique_ptr является непрерывным std::auto_ptr. Он запрещает во время компиляции поведения, которые были часто ошибки при использовании std::auto_ptr. Поэтому, если вы используете std::auto_ptr с необходимой осторожностью, переключение на std::unique_ptr должно быть простым. Если вы полагались на странное поведение std::auto_ptr, то вам все равно нужно реорганизовать свой код.

33 голосов
/ 10 августа 2010

AFAIK, unique_ptr не является прямой заменой. Основным недостатком, который он исправляет, является неявная передача права собственности.

std::auto_ptr<int> a(new int(10)), b;
b = a; //implicitly transfers ownership

std::unique_ptr<int> a(new int(10)), b;
b = std::move(a); //ownership must be transferred explicitly

С другой стороны, unique_ptr будет иметь совершенно новые возможности: они могут храниться в контейнерах.

27 голосов
/ 03 октября 2014

У Херба Саттера есть хорошее объяснение: ПОЛУЧИЛ # 89 :

Какое дело с auto_ptr? auto_ptr наиболее мягко охарактеризован как доблестная попытка создать unique_ptr до C ++ имел ход семантики. auto_ptr устарел и не должен использоваться в новом коде.

Если у вас есть auto_ptr в существующей кодовой базе, когда вы получаете шанс попробуйте выполнить глобальный поиск и замену auto_ptr на unique_ptr; Подавляющее большинство применений будет работать одинаково, и это может ошибка времени компиляции) или исправьте (молча) ошибку или два, которые вы не знали не было.

Другими словами, хотя глобальный поиск и замена может временно «сломать» ваш код, вы все равно должны это сделать: это может занять некоторое время, чтобы исправить ошибки компиляции, но избавит вас от гораздо больших проблем в в долгосрочной перспективе.

...