Указатель NULL
- это тот, который указывает на никуда. Когда вы разыскиваете указатель p
, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p
является нулевым указателем, местоположение, хранящееся в p
, является nowhere
, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception
.
В общем, это потому, что что-то не было правильно инициализировано.
Вот код для выполнения того, что вы хотите (вероятно, не скомпилируется, так как у меня нет наддува, и я пишу его из памяти):
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
).
Это почти ортогональные проблемы. shared_ptr
не играет никакой роли в распределении объектов.
Там, где это относится к , находится удаление из памяти , на которую больше не ссылаются. Если вы выделили что-то кроме кучи по умолчанию, вам нужно предоставить пользовательское средство удаления
Очевидное решение:
Создайте свою собственную функцию make_shared
и принудительно используйте этот метод для создания shared_ptr
. Те, кто исходит из Правил, подлежат наказанию.
Примечание:
Кажется, существует путаница с ролью shared_ptr
. Его роль состоит в том, чтобы управлять памятью, которую ВЫ выделили, однако для этого требуется некоторое собственное выделение (счетчик и удалитель), поэтому вы можете передать ему распределитель для них.