Есть ли некоторый эквивалентный класс для C++ 1x's станд.:: unique_ptr в библиотеках повышения? Поведение, которое я ищу, является способностью иметь безопасную от исключения функцию фабрики, как так...
std::unique_ptr<Base> create_base()
{
return std::unique_ptr<Base>(new Derived);
}
void some_other_function()
{
std::unique_ptr<Base> b = create_base();
// Do some stuff with b that may or may not throw an exception...
// Now b is destructed automagically.
}
Править: Прямо сейчас я использую этот взлом, который походит на лучшее, я могу достигнуть эту точку...
Base* create_base()
{
return new Derived;
}
void some_other_function()
{
boost::scoped_ptr<Base> b = create_base();
// Do some stuff with b that may or may not throw an exception...
// Now b is deleted automagically.
}
Невозможно создать что-то вроде unique_ptr
без C++0x (где он является частью стандартной библиотеки, и поэтому Boost не нужно его предоставлять).
В частности, без rvalue references, которые являются особенностью C++0x, надежная реализация unique_ptr
невозможна, с Boost или без него.
В C++03 есть несколько возможных альтернатив, хотя каждая из них имеет свои недостатки.
boost::shared_ptr
- вероятно, самая простая замена с точки зрения возможностей. Вы можете смело использовать его везде, где иначе использовали бы unique_ptr
, и он будет работать. Просто это будет не так эффективно из-за дополнительного подсчета ссылок. Но если вы ищете простую замену, способную обрабатывать все, что может unique_ptr
, то это, вероятно, лучший вариант. (Конечно, shared_ptr
может делать гораздо больше, но его также можно просто использовать как замену unique_ptr
.)boost::scoped_ptr
похож на unique_ptr
, но не позволяет передавать права собственности. Он отлично работает, если интеллектуальный указатель предназначен для сохранения эксклюзивного владения в течение всего срока службы. std::auto_ptr
работает очень похоже на unique_ptr
, но имеет несколько ограничений, в основном то, что его нельзя хранить в контейнерах стандартной библиотеки. Если вам просто нужен указатель, который позволяет передавать права собственности, но не предназначен для хранения в контейнерах или копирования, то это, вероятно, хороший вариант. Возможно, вы захотите попробовать "доказательство концепции" unique_ptr<>
реализации Говарда Хиннанта для C++03 (дисклеймер - я не пробовал):
Один из его примеров возвращает unique_ptr
:
unique_ptr<int> factory(int i)
{
return unique_ptr<int>(new int(i));
}
Я использовал unique_ptr Говарда Хиннанта. Если вы не очень хорошо умеете читать безумные ошибки метапрограммирования от компилятора, то лучше воздержаться. Однако в 90% случаев он действует так же, как unique_ptr.
В противном случае я бы посоветовал передавать параметры как boost::scoped_ptr&
и выполнять внутреннюю подкачку для передачи прав собственности. Для получения возвращаемых значений в стиле unique_ptr используйте auto_ptr
. Захватите возвращаемое значение auto_ptr
в shared_ptr
или scoped_ptr
, чтобы избежать прямого использования auto_ptr
.