TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.35K subscribers
Post #164 1.57K
В чем проблема auto_ptr

В стародавние времена, когда еще мамонты ходили по земле, был выпущен стандарт С++98, в стандартной библиотеке которого был один интересный умный указатель std::auto_ptr. Этот шаблон был порождением страхов и мучений. Ибо еще со времен, когда даже динозавры существовали, этим динозаврам было сложно управлять обычными сырыми указателями. И всегда было стремление обезопасить работу с ними в С++. И вот настал тот момент, когда появилось первое стандартное средство безопасного управления памятью. Однако первый блин, как это часто бывает, получился комом...

Конкретно std::auto_ptr реализовывал семантику владения объектом. То есть в конструкторе указатель захватывался, а в деструкторе всегда освобождался. Применение идиомы RAII в самой красе. Но давайте-ка взглянем пристальнее на механизм передачи владения.

Что мы имеет в С++98/03. Мы имеем 2 специальных метода, которые помогают перенимать характеристики другого объекта. Это копирующий конструктор и копирующий оператор присваивания. На этом все. Как можно на этих двух сущностях имплементировать передачу владения?

Очень и очень криво. Копирование на то и копирование, что не изменяет исходный объект. По крайней мере это подразумевают пользователи классов. Однако в целом, мы можем почти все что угодно делать внутри копирующих методов. Ну вот создатели auto_ptr и сделали грязь. Там конструктор и оператор присваивания принимают не константную ссылку, как обычно, а просто ссылку. Внутри они копируют указатель на ресурс из переданного объекта и помещают его в текущий. А указатель на ресурс переданного объекта зануляют.

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

От этого уже идет, что auto_ptr не соответствует требованиям CopyConstuctible и CopyAssignable стандартных контейнеров, поэтому создание и использование инстанса контейнера с auto_ptr ведет к неопределенному поведению.

Конечно, это все было из-за отсутствия move-семантики. Язык просто был недостаточно мощным, чтобы реализовать семантику владения.

Однако в С++11 проблема была решена. Введена мув-семантика и std::unique_ptr, в котором реализовали идею авто указателя. При небольшом рефакторинге и замене std::auto_ptr на unique_ptr проблем больше не было. И потребность в использовании бустовых аналогов тоже отпала.

И комитет решил на радостях задеприкейтить auto_ptr, а затем и вовсе удалил его в С++17 за ненабностью.

Fix your mistakes. Stay cool.

#inteview #cpp11 #cpp17
  • 🔥 19
  • 👍 6
  • 😁 2
  • ❤ 1
More from @grokaemcpp
  1. Oct 14, 2026​​Что внутри std::condition_variable? #опытным Более менее все знакомы с примитивом синхро…
  2. Oct 12, 2026​​WAT #новичкам Как вы думаете, результат выражения: bool math = -1 < 1U; будет правдой ил…
  3. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  4. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  5. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  6. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →