Есть ли какие-либо причины использовать автоматический ptr?


Прочитав объяснение Джоссутиса по auto_ptr из его книги STL, у меня сложилось сильное впечатление, что какую бы задачу я ни попытался использовать, я бы на 100% провалился из-за одной из многих ловушек auto_ptr.

Мой вопрос: есть ли какие-либо реальные жизненные задачи, где auto_ptr действительно полезен и хорошо вписывается в них?

4 15

4 ответа:

Ясно, что auto_ptr проигрывает против unique_ptr.

Теперь, в "строгом C++03 без boost" мире, я использую auto_ptr довольно часто, в частности:

  • для "фабричных функций-членов", которые возвращают динамически выделенный экземпляр данного типа: Мне нравится тот факт, что использование std::auto_ptr в возвращаемом типе эксплицирует, что объект должен быть удален
  • в функциях, которые выделяют объект перед попыткой вставить его в контейнер после этого : например, чтобы release() только если std::map<>::insert возвращает, что вставка прошла успешно
  • в потоковой процедуре, которая извлекает элементы из очереди сообщений, мне нравится хранить элемент pop'ed в const std::auto_ptr, чтобы было ясно, что сообщение будет уничтожено, несмотря ни на что.

Я бы сказал, что его можно использовать, но это не лучший вариант.

Во-первых, это вопрос года или меньше, и auto_ptr официально считается устаревшим. Во-вторых, существует превосходящая альтернатива: unique_ptr. доктор Строструп однажды сказал О unique_ptr:

"Каким должен был быть auto_ptr" (но что мы не могли написать в C++98)

Таким образом, если у вас нет выбора, auto_ptr не является хорошим выбором. Главным образом потому, что большинство компиляторов C++ в наши дни реализуют move semantics и предоставляют unique_ptr.

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

Я использую std::auto_ptr умеренно часто, чтобы обеспечить безопасность исключений. То есть, чтобы предотвратить утечку памяти в случае, если часть метода создает исключение.

Например:

Foo &Container::addFoo(
   const std::string &name
   )
{
  // The post conditions of the method require that the new Foo
  // has been added to this container, but the addition method
  // may throw exceptiona
  std::auto_ptr< Foo > foo(new Foo(name));

  foo->twiddle();// may throw
  this->addFoo(*foo);// record reference. May throw

  return *foo.release();
}

Отредактировано: уточнил, что this->addFoo(*foo) записывает ссылку.