auto_ptr
и shared_ptr
решают совершенно разные проблемы. Одно не заменяет другое.
auto_ptr
- это тонкая оболочка вокруг указателей для реализации семантики RAII , так что ресурсы всегда высвобождаются, даже при возникновении исключений. auto_ptr
вообще не выполняет подсчет ссылок и т.п., он не заставляет несколько указателей указывать на один и тот же объект при создании копий. На самом деле все совсем иначе. auto_ptr
- один из немногих классов, в которых оператор присваивания изменяет объект source . Рассмотрим этот бесстыдный плагин со страницы википедии auto_ptr :
int *i = new int;
auto_ptr<int> x(i);
auto_ptr<int> y;
y = x;
cout << x.get() << endl; // Print NULL
cout << y.get() << endl; // Print non-NULL address i
Обратите внимание, как выполнение
y = x;
изменяет не только y, но и x.
Шаблон boost :: shared_ptr
делает это легко обрабатывать несколько указателей на один и тот же объект, и объект удаляется только после того, как последняя ссылка на него вышла из области видимости. Эта функция бесполезна в вашем сценарии, который (пытается) реализовать Singleton . В вашем сценарии всегда либо 0 ссылок на 1 ссылку на единственный объект класса, если таковой имеется.
По сути, объекты auto_ptr
и shared_ptr
объекты имеют совершенно разную семантику. (который' s, почему вы не можете использовать первое в контейнерах, но делать это с последними - это нормально), и я очень надеюсь, что у вас есть хорошие тесты, чтобы отловить любые регрессии, которые вы внесли при переносе кода. : -}
Другие ответили, почему это код использует auto_ptr
вместо shared_ptr
. Чтобы ответить на другие ваши вопросы:
Что / как я могу заменить эту реализацию?
Используйте либо boost :: scoped_ptr
, либо unique_ptr
(доступно как в Boost, так и в новом C ++ стандарт). И scoped_ptr
, и unique_ptr
обеспечивают строгое владение (и не накладывают накладные расходы на подсчет ссылок) и избегают неожиданной семантики удаления при копировании auto_ptr
.
Кроме того, есть ли другие причины, по которым вы могли бы рассмотреть возможность использования auto_ptr
вместо shared_ptr
? Видите ли вы какие-либо проблемы, связанные с переходом на shared_ptr
в будущем?
Лично я бы не стал использовать auto_ptr
. Удаление при копировании слишком неинтуитивно. Херб Саттер, кажется, согласен . Переключение на scoped_ptr
, unique_ptr
или shared_ptr
не должно вызывать проблем. В частности, shared_ptr
должен быть заменой, если вас не волнуют накладные расходы на подсчет ссылок. scoped_ptr
- это оперативная замена, если вы не используете возможности auto_ptr
по передаче права собственности. Если вы используете передачу права собственности, то unique_ptr
- это почти полная замена, за исключением того, что вам нужно вместо этого явно вызвать move
для передачи владения. См. Пример здесь .
auto_ptr - единственный вид интеллектуального указателя, который я использую. Я использую его, потому что я не использую Boost, и потому что я обычно предпочитаю, чтобы мои бизнес-классы / классы, ориентированные на приложение, явно определять семантику и порядок удаления, а не зависеть от коллекции или отдельные интеллектуальные указатели.