Есть ли причина использовать 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)
записывает ссылку.