【问题标题】:Custom (pool) allocator with boost shared_ptr带有 boost shared_ptr 的自定义(池)分配器
【发布时间】:2011-02-24 01:34:53
【问题描述】:

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

【问题讨论】:

    标签: c++ boost shared-ptr allocator


    【解决方案1】:

    这是执行您想要的操作的代码(可能无法编译,因为我手头没有 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();
    

    我在两个不同的项目中实施了两次。在两者中,create 和 destroy 函数是同步的(您可以在分配器的使用周围添加 boost::mutex 锁)并且它们是工厂类的成员(并且 destroy 的签名通过boost::bind) 的用法。

    您还可以通过在 boost::shared_ptr 构造函数中直接绑定 object_pool&lt;YourClass&gt;::destroy 来避免编写两个额外的函数(destroy 和 create)。

    我现在都懒得写了:)。

    编辑(将我的答案评论移到此处以进行代码格式化):

    绑定销毁函数:

    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 实例)。

    【讨论】:

    • 谢谢,这就是我要找的。我很想看看它是如何使用工厂类完成的,我在绑定销毁函数时遇到了问题。
    • 你知道construct不接受任何争论是否有技术原因?
    • 我最近做了一些与模板池类非常相似的事情,并在这里写了:burgundywall.com/post/shared_pool
    【解决方案2】:

    明显的解决方案:

    创建您自己的make_shared 函数并强制使用此方法创建shared_ptr。凡是从规则中衍生出来的人都会受到惩罚。

    注意:

    shared_ptr 的角色似乎有些混淆。它的作用是管理你分配的内存,但是这样做需要分配它自己的一些内存(计数器和删除器),因此你可以为它们传递一个分配器。

    【讨论】:

    • 您不能将boost::allocate_shared 与boost::pool_alloc 一起使用吗?
    【解决方案3】:

    这些几乎是正交的问题。 shared_ptr 不参与对象的分配。

    它关注的地方是删除不再引用的内存。如果你从默认堆以外的任何地方分配,你需要provide a custom deleter

    【讨论】:

    • 据我了解,shared_ptr 可以定义为采用自定义分配器:template&lt;class Y, class D, class A&gt; shared_ptr(Y * p, D d, A a); 问题是,如果我要使用 Boost 的 pool_alloc,D 会发生什么
    • 分配器用于计数器对象
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多