【问题标题】:Custom deleter for boost shared_ptrboost shared_ptr 的自定义删除器
【发布时间】:2012-03-31 17:36:49
【问题描述】:

我有一个关于向boost::shared_ptr 构造函数提供自定义删除方法的问题。

例如,我有一个 GameObjectFactory 类,它创建/销毁 GameObjects。它有一个MemoryManager的实例,可以Allocate()/Deallocate()内存。 CreateObject()返回一个GameObject,通过MemoryManager分配,封装在一个boost::shared_ptr中。

boost::shared_ptr 破坏时,它应该调用我的MemoryManager->Deallocate() 方法。但是我做错了;我收到这些错误:

error C2276: '&' : illegal operation on bound member function expression
error C2661: 'boost::shared_ptr<T>::shared_ptr' : no overloaded function takes 2 arguments

我已经阅读了 boost 文档以及我从 stackoverflow 获得的点击量,但我无法正确理解。我不明白为什么以下不工作。

这是我的代码;

#ifndef _I_GAMEOBJECT_MANAGER_H
#define _I_GAMEOBJECT_MANAGER_H

#include "../../Thirdparty/boost_1_49_0/boost/smart_ptr/shared_ptr.hpp"

#include "EngineDefs.h"
#include "IMemoryManager.h"
#include "../Include/Core/GameObject/GameObject.h"

namespace Engine
{
    class IGameObjectFactory
    {
    public:
        virtual ~IGameObjectFactory() { }

        virtual int32_t Init() = 0;
        virtual bool Destroy() = 0;
        virtual bool Start() = 0;
        virtual bool Stop() = 0;
        virtual bool isRunning() = 0;
        virtual void Tick() = 0;

        template <class T>
        inline boost::shared_ptr<T> CreateObject()
        {
            boost::shared_ptr<T> ptr((T*) mMemoryMgr->Allocate(sizeof(T)),&mMemoryMgr->Deallocate);


            return ptr;
        }

        template <class T>
        inline boost::shared_ptr<T> CreateObject(bool UseMemoryPool)
        {
            boost::shared_ptr<T> ptr((T*) mMemoryMgr->Allocate(sizeof(T),UseMemoryPool), &mMemoryMgr->Deallocate);


            return ptr;
        }

    protected:
        IMemoryManager* mMemoryMgr;
    };

}

#endif

【问题讨论】:

    标签: c++ memory-management boost shared-ptr smart-pointers


    【解决方案1】:

    shared_ptr 期望删除器是一个接受单个参数的函数,该参数是指针类型 (T*)。您正在尝试将成员函数传递给它,并且由于 shared_ptr 没有引用 IMemoryManager 对象,因此它将不起作用。为了解决这个问题,创建一个接受指针对象并调用 IMemoryManager::Deallocate() 的静态成员函数:

    template <class T>
    static void Deallocate(T* factoryObject)
    {
        factoryObject->mMemoryMgr->Deallocate();
    }
    

    然后您可以像这样创建 shared_ptr:

    boost::shared_ptr<T> ptr((T*) mMemoryMgr->Allocate(sizeof(T),UseMemoryPool), &IGameObjectFactory::Deallocate<T>);
    

    【讨论】:

    • 我仍然收到以下错误:错误 C2661:'boost::shared_ptr::shared_ptr':没有重载函数需要 2 个参数使用最新的 boost 构建
    • @KaiserJohaan:那么,您使用的是哪个版本的 Boost?
    【解决方案2】:

    boost::shared_ptr 以及 std::shared_ptr 将谓词用作自定义删除器。所以你可以传递一个函数,或者一个仿函数。您传递的是指向成员函数的指针,这不足以调用它,因为您没有指向对象的指针。详情请关注Pointers to member functions。有很多方法可以实现你想要的,我会编写我自己的简单仿函数,它会记住一个对象工厂指针,并在shared_ptr 调用时调用适当的方法来删除它。此外,请考虑使用intrusive_ptr,除非您确实需要shared_ptr。效率更高。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多