Грокаем C++
7.53K subscribers
25 photos
3 files
336 links
Два сеньора C++ - Владимир и Денис - отныне ваши гиды в этом дремучем мире плюсов.

По всем вопросам - @ninjatelegramm

Менеджер: @Spiral_Yuri
Реклама: https://telega.in/c/grokaemcpp
Мы на TGstat: https://tgstat.ru/channel/@grokaemcpp/stat
Download Telegram
В чем проблема 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