使用 boost shared_ptr 的自定义(池)分配器

26
我希望对象由shared_ptr管理,且从池中分配,比如Boost的Pool接口,如何实现?
3个回答

21

这是你所需的代码(可能无法编译,因为我手头没有 boost 并且我是从记忆中编写的):

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函数的签名也因为使用了boost::bind而修改为void (YourClass*)

你还可以通过在boost::shared_ptr构造函数中直接绑定object_pool<YourClass>::destroy来避免写两个额外的函数(destroycreate)。

我现在懒得写那么多代码了 :)

编辑(将我的答复评论移动到这里方便代码格式化):

绑定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 实例的 this 指针将无效,并且在 shared_ptr 删除 YourClass 实例时会导致您的应用程序崩溃)。


谢谢,这正是我在寻找的。我很想看看如何使用工厂类来完成它,我在绑定销毁函数方面遇到了问题。 - myahya
你知道 construct 不接受任何参数的技术原因吗? - Stephan Dollberg
我最近使用一个模板化的池类做了类似的事情,并在这里写了一篇文章:https://www.burgundywall.com/post/shared_pool - Kurt

4
明确的解决方案:
创建自己的“make_shared”函数,并强制使用该方法来创建“shared_ptr”。那些不遵守规则的人将受到惩罚。
注意: 有一些人对“shared_ptr”的角色存在混淆。它的角色是管理你分配的内存,但为了实现这一点,它需要进行一些自身的分配(计数器和删除器),因此你可以为其传递一个分配器。

3
你能否使用boost::pool_allocboost::allocate_shared一起使用? - dvide

1

这些几乎是正交的问题。shared_ptr在对象的分配中没有任何作用。

它所涉及的是不再被引用的内存的删除。如果您从除默认堆之外的任何地方进行了分配,则需要提供自定义删除器


据我所理解,shared_ptr 可以定义为使用自定义分配器:template<class Y, class D, class A> shared_ptr(Y * p, D d, A a);问题是,如果我要使用 Boost 的 pool_alloc,D 参数该如何处理? - myahya
分配器是用于计数器对象的。 - philsquared

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接