Я хочу, чтобы объекты, управляемые shared_ptr, были выделены из пула, например, интерфейс Boost Pool, как это можно достичь?
Пользовательский (пул) распределитель с boost shared_ptr
Ответ 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
не участвует в распределении объектов.
В том случае, когда речь заходит об удалении памяти, больше не ссылающейся. Если вы выделили ничего, кроме кучи по умолчанию, вам нужно предоставить пользовательский отказ