No-op deallocator для boost:: shared_ptr
Есть ли резервный активатор запаса no-op в Boost для использования с boost::shared_ptr
для статических объектов и т.д.
Я знаю, что это ультра-тривиально писать, но я не хочу посыпать свой код дополнительными крошечными функциями, если есть уже один доступный.
Ответы
Ответ 1
Да, есть один здесь:
#include <boost/serialization/shared_ptr.hpp> // for null_deleter
class Foo
{
int x;
};
Foo foo;
boost::shared_ptr< Foo > sharedfoo( &foo, boost::serialization::null_deleter() );
Конечно, существует опасность, что вам нужно знать, что функция, которую вы вызываете, не хранит shared_ptr для последующего использования, поскольку она фактически противоречит политике shared_ptr в том, что основной объект остается в силе до тех пор, пока то из последнего экземпляра shared_ptr.
Ответ 2
Решение использует Boost.Lambda:
#include <boost/shared_ptr.hpp>
#include <boost/lambda/lambda.hpp>
int main()
{
int *p = new int(5);
{
boost::shared_ptr<int> sp(p, boost::lambda::_1);
}
delete p;
}
'boost:: lambda:: _ 1' создает пустой функтор, который принимает один аргумент.
Вероятно, вы захотите добавить комментарий //, чтобы люди знали, почему вы это сделали.
Ответ 3
Разве не было бы проще просто взять дополнительную ссылку, чтобы деллалокатор никогда не назывался? (Хотя это еще не очень чисто.)
Я не могу сказать, что в Boost нет функции, которая бы выполняла эту работу, но это не похоже на то, что они хотели бы включить.
РЕДАКТИРОВАТЬ: Прочитав комментарии и небольшую документацию, это сводится к следующему:
-
Исходная утечка. В какой-то момент выполните следующее:
new shared_ptr( my_global_shared_ptr );
Преимущества: концептуально легко. Недостатки: вы утечка чего-то в кучу.
-
Пользовательский освободитель. Поскольку shared_ptr
требует мало функции деллалокатора, функция анонимного удостоверения, подобная той, которая предусмотрена в другом ответе, будет выполнена.
Преимущества: использует Boost и не имеет никаких накладных расходов. Недостатки: требуется небольшая документация.
-
Нестатический глобальный объект. Если для вашего объекта существует глобальный shared_ptr
, это должен быть единственный доступ к нему. Замените объявление глобального с помощью shared_ptr
, инициализированного new my_class
. Я думаю, что это лучше всего.
Ответ 4
Там есть билет для этого на трекер-бугере Boost: https://svn.boost.org/trac/boost/ticket/1913 - долгое время не было активности, пока не стало какое-то ропот две недели назад.
Ответ 5
FWIW, это то, что я использую.
Я использую его в модульных тестах, чтобы адаптировать локальный файл к shared_ptr.
// The class NoOp_sptr_Deleter can be used to construct a shared_ptr<>()
// that will NOT delete the pointee.
// This can be helpful in unit-testing. Wrapping a local as a shared_ptr.
// Do take care with the lifetimes though.
struct NoOp_sptr_Deleter
{
void operator()(void const *) const {}
};
template<typename T>
boost::shared_ptr<T> FakeSharedPtrFromRef(T& aRef)
{
return boost::shared_ptr<T>(&aRef, NoOp_sptr_Deleter() );
}
Ответ 6