KaiserJohaan
KaiserJohaan

Reputation: 9240

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

Upvotes: 3

Views: 10122

Answers (2)

zdan
zdan

Reputation: 29480

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>);

Upvotes: 8

user405725
user405725

Reputation:

boost::shared_ptr, as well as std::shared_ptr takes a predicate as a custom deleter. So you can pass a function, or a functor. What you are passing is a pointer to a member function, which is not enough to invoke it since you don't have a pointer to an object. You have to study Pointers to member functions for details. There are many ways to achieve what you want, I'd write my own simple functor that remembers an object factory pointer, and calls an appropriate method to delete it once invoked by the shared_ptr. Also, consider using intrusive_ptr unless you really need shared_ptr. It is a lot more efficient.

Upvotes: 1

Related Questions