Есть ли причина использовать auto_ptr?

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

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

4 ответа

Решение

Очевидно, что auto_ptr проигрывает против unique_ptr,

Теперь, в мире "строгого C++03 без повышения", я использую 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) записывает ссылку.

Другие вопросы по тегам