Пользовательский (пул) распределитель с бустом shared_ptr - PullRequest
26 голосов
/ 26 мая 2010

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

Ответы [ 3 ]

21 голосов
/ 26 мая 2010

Вот код для выполнения того, что вы хотите (вероятно, не скомпилируется, так как у меня нет наддува, и я пишу его из памяти):

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();

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

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

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

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

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

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 удален, указатель this, переданный экземпляру shared_ptr, будет недействительным - и вылетит из приложения, когда удаляется shared_ptr YourClass экземпляр).

4 голосов
/ 26 мая 2010

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

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

Примечание:

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

1 голос
/ 26 мая 2010

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

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

...