Подтвердить что ты не робот

No-op deallocator для boost:: shared_ptr

Есть ли резервный активатор запаса no-op в Boost для использования с boost::shared_ptr для статических объектов и т.д.

Я знаю, что это ультра-тривиально писать, но я не хочу посыпать свой код дополнительными крошечными функциями, если есть уже один доступный.

4b9b3361

Ответ 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() );
}