Search code examples
c++memory-managementboostshared-ptrsmart-pointers

Custom deleter for boost shared_ptr


I have a question regarding providing a custom delete-method to boost::shared_ptr constructor.

For example, I have a GameObjectFactory class which creates/destroys GameObjects. It has an instance of a MemoryManager, which can Allocate()/Deallocate() memory. CreateObject() returns a GameObject, allocated through the MemoryManager, encapsulated in a boost::shared_ptr.

When the boost::shared_ptr destructs, it should call my MemoryManager->Deallocate() method. However I can't get it right; I get these errors:

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

I have read the boost documentation and the hits I got from stackoverflow, yet I cannot get it right. I dont understand why the below dosnt work.

Here's my code;

#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

Solution

  • shared_ptr expects the deleter to be a function that accepts a single argument that is the pointer type (T*). You are trying to pass it a member function, and since shared_ptr has no reference to the IMemoryManager object, it won't work. To get around this, create a static member function that accepts the pointer object and calls IMemoryManager::Deallocate() :

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

    You can then create your shared_ptr like this:

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