2012-03-31 4 views
2

У меня возник вопрос о предоставлении настраиваемого метода удаления для конструктора boost::shared_ptr.Пользовательский удалятель для 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, но я не могу получить это права. Я не понимаю, почему работает ниже dosnt.

Это мой код;

#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 

ответ

7

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

Я до сих пор получаю следующая ошибка: ошибка C2661: 'boost :: shared_ptr :: shared_ptr': никакая перегруженная функция не принимает 2 аргумента Использование последней сборки boost – KaiserJohaan

+0

@KaiserJohaan: Ну, какую версию Boost вы используете? –

+0

Я использую boost 1.49.0 – KaiserJohaan

1

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

Смежные вопросы