Есть ли какие-либо причины использовать автоматический ptr?
Прочитав объяснение Джоссутиса по auto_ptr из его книги STL, у меня сложилось сильное впечатление, что какую бы задачу я ни попытался использовать, я бы на 100% провалился из-за одной из многих ловушек auto_ptr.
Мой вопрос: есть ли какие-либо реальные жизненные задачи, где auto_ptr действительно полезен и хорошо вписывается в них?
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)записывает ссылку.