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

Указатель NULL - это тот, который указывает на никуда. Когда вы разыскиваете указатель p, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p является нулевым указателем, местоположение, хранящееся в p, является nowhere, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception.

В общем, это потому, что что-то не было правильно инициализировано.

26
задан myahya 26 May 2010 в 08:14
поделиться

3 ответа

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

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).

21
ответ дан utnapistim 26 May 2010 в 08:14
поделиться

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

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

1
ответ дан Community 26 May 2010 в 08:14
поделиться

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

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

Примечание:

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

4
ответ дан 28 November 2019 в 07:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: