Пользовательский удалитель для boost shared_ptr - PullRequest
3 голосов
/ 31 марта 2012

У меня есть вопрос относительно предоставления пользовательского метода удаления конструктору 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

Я прочитал документацию по бусту и хиты, полученные от 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

Ответы [ 2 ]

8 голосов
/ 31 марта 2012

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>);
1 голос
/ 31 марта 2012

boost::shared_ptr, а также std::shared_ptr принимает предикат в качестве пользовательского средства удаления. Таким образом, вы можете передать функцию или функтор. То, что вы передаете, это указатель на функцию-член, которой недостаточно для ее вызова, поскольку у вас нет указателя на объект. Вы должны изучить Указатели на функции-члены для деталей. Есть много способов достичь того, чего вы хотите, я бы написал свой собственный простой функтор, который запоминает указатель фабрики объектов и вызывает соответствующий метод для его удаления, когда-то вызываемый shared_ptr. Кроме того, рассмотрите возможность использования intrusive_ptr, если вам действительно не нужен shared_ptr. Это намного эффективнее.

...