Reputation: 9240
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
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
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