2012-03-31 3 views
2

Ich habe eine Frage in Bezug auf die Bereitstellung einer benutzerdefinierten delete-Methode zu boost::shared_ptr Konstruktor.Benutzerdefinierte Löscher für Boost shared_ptr

Zum Beispiel habe ich eine GameObjectFactory Klasse, die GameObjects erstellt/zerstört. Es hat eine Instanz von MemoryManager, die Allocate()/Deallocate() Speicher kann. CreateObject() gibt eine GameObject zurück, zugeteilt durch die MemoryManager, gekapselt in einer boost::shared_ptr. Wenn die boost::shared_ptr zerstört, sollte es meine MemoryManager->Deallocate() Methode aufrufen. Aber ich kann es nicht richtig machen; Ich erhalte diesen Fehler:

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

ich die Boost-Dokumentation gelesen habe und die Hits ich von Stackoverflow bekam, aber ich kann es nicht richtig machen. Ich verstehe nicht, warum die unten genannten Dosnt arbeiten.

Hier ist mein 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 

Antwort

7

shared_ptr erwartet, dass der Deleter eine Funktion ist, die ein einzelnes Argument des Zeigertyps akzeptiert (T*). Sie versuchen, eine Elementfunktion zu übergeben, und da shared_ptr keinen Verweis auf das IMemoryManager-Objekt hat, wird es nicht funktionieren. Um dies zu umgehen, erstellen Sie eine statische Member-Funktion, die den Zeiger-Objekt und ruft IMemoryManager :: Ausplanen() akzeptiert:

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

Sie können dann erstellen Sie Ihre Shared_ptr wie folgt aus:

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

ich immer noch das bekommen Folgefehler: Fehler C2661: 'boost :: shared_ptr :: shared_ptr': keine überladene Funktion benötigt 2 Argumente Verwenden der neuesten Boost-Build – KaiserJohaan

+0

@KaiserJohaan: Nun, welche Version von Boost verwenden Sie? –

+0

Ich verwende Boost 1.49.0 – KaiserJohaan

1

boost::shared_ptr sowie std::shared_ptr nimmt ein Prädikat als benutzerdefinierten deleter. Sie können also eine Funktion oder einen Funktor übergeben. Was Sie übergeben, ist ein Zeiger auf eine Elementfunktion, die nicht ausreicht, um sie aufzurufen, da Sie keinen Zeiger auf ein Objekt haben. Sie müssen Pointers to member functions für Details studieren. Es gibt viele Möglichkeiten, um zu erreichen, was Sie wollen, ich würde meinen eigenen einfachen Funktor schreiben, der sich einen Objektfactory-Zeiger merkt, und eine geeignete Methode aufruft, um ihn zu löschen, sobald er von shared_ptr aufgerufen wurde. Ziehen Sie auch die Verwendung von intrusive_ptr in Betracht, es sei denn, Sie benötigen wirklich shared_ptr. Es ist viel effizienter.

Verwandte Themen