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

Пользовательский (пул) распределитель с boost shared_ptr

Я хочу, чтобы объекты, управляемые shared_ptr, были выделены из пула, например, интерфейс Boost Pool, как это можно достичь?

4b9b3361

Ответ 1

Здесь код, который вы хотите сделать (возможно, не будет компилироваться, поскольку у меня нет поддержки под рукой, и я пишу его из памяти):

class YourClass; // your data type, defined somewhere else

boost::object_pool<YourClass> allocator;

void destroy(YourClass* pointer)
{
    allocator.destroy(pointer);
}

boost::shared_ptr<YourClass> create()
{
    // usage of object_pool<??>::construct requires that you have a 
    // YourClass::YourClass(void) defined. If you need to pass arguments
    // to the new instance, you need to do that separately.
    // 
    // for example using a YourClass::Initialize(your,parameters,here) method
    // before returning from this function
    return boost::shared_ptr<YourClass>( allocator.construct(), &destroy );
}

// usage:
boost::shared_ptr<YourClass>  newObject = create();

Я реализовал это дважды, в двух разных проектах. В обоих случаях функции create и destroy были синхронизированы (вы можете добавить блокировку boost::mutex вокруг использования распределителя), и они были членами класса factory (а подпись destroy была изменена на void (YourClass*) через использование boost::bind).

Вы также можете не записывать две дополнительные функции (destroy и create) путем привязки object_pool<YourClass>::destroy в конструкторе boost:: shared_ptr.

Мне слишком ленится написать все это сейчас:).

Изменить (переместил мой ответ на комментарий для форматирования кода):

Чтобы связать функцию destroy:

class ClassFactory
{
    boost::object_pool<YourClass> allocator;
public:
    boost::shared_ptr<YourClass> create()
    {
        return boost::shared_ptr<YourClass>(
            allocator.construct(),
            boost::bind(&ClassFactory::destroy, this, _1) );
    }

    void destroy(YourClass* pointer)
    {
        allocator.destroy(pointer);
    }
};

ClassFactory должен иметь более длительный срок службы, чем shared_ptr (если экземпляр ClassFactory удален, этот указатель, переданный экземпляру shared_ptr, будет недействительным) и приведет к краху вашего приложения, когда shared_ptr удалит экземпляр YourClass).

Ответ 2

Очевидное решение:

Создайте собственную функцию make_shared и принудительно используйте этот метод для создания shared_ptr. Те, кто вытекает из Правила, наказываются.

Примечание:

Кажется, существует путаница с ролью shared_ptr. Его роль состоит в том, чтобы управлять памятью, чем вы выделили, однако для этого требуется некоторое выделение своего (счетчик и дебетер), поэтому вы можете передать ему распределитель для них.

Ответ 3

Это почти ортогональные проблемы. shared_ptr не участвует в распределении объектов.

В том случае, когда речь заходит об удалении памяти, больше не ссылающейся. Если вы выделили ничего, кроме кучи по умолчанию, вам нужно предоставить пользовательский отказ