c++ - tutorial - std::unique_ptr




Verwendung eines benutzerdefinierten Deleters mit std:: shared_ptr (2)

Dieser Code enthält ein Beispiel für eine gemeinsam genutzte Zeigerkonstruktion mit dem Deleter als Objektmethode. Es zeigt die zu verwendende std::bind Anweisung an.

Das Beispiel ist ein einfacher Objektrecycler. Wenn der letzte Verweis auf das Objekt zerstört wird, wird das Objekt in den freien Objektpool im Recycler zurückgegeben.

Der Recyler kann einfach in einen Objekt-Cache geändert werden, indem ein Schlüssel zu den Methoden get() und add() und die Objekte in einer std::map gespeichert werden.

class ObjRecycler
{
private:
    std::vector<Obj*> freeObjPool;
public:
    ~ObjRecycler()
    {
        for (auto o: freeObjPool)
            delete o;
    }

    void add(Obj *o)
    {
        if (o)
            freeObjPool.push_back(o);
    }

    std::shared_ptr<Obj> get()
    {
        Obj* o;
        if (freeObjPool.empty())
            o = new Obj();
        else
        {
            o = freeObjPool.back();
            freeObjPool.pop_back();
        }
        return std::shared_ptr<Obj>(o, 
             std::bind(&ObjRecycler::add, this, std::placeholders::_1));
    }
}

Ich versuche herauszufinden, wie man std :: shared_ptr mit einem benutzerdefinierten Deleter verwendet. Im Einzelnen verwende ich es mit SDL_Surface als:

std::shared_ptr<SDL_Surface>(SDL_LoadBMP(....),SDL_FreeSurface);

was kompiliert und läuft gut. Ich möchte jedoch mein eigenes Deleter ausprobieren und kann nicht herausfinden, wie das geht. Die Dokumentation zu SDL_FreeSurface finden Sie hier:

http://sdl.beuc.net/sdl.wiki/SDL_FreeSurface

in dem ich finde das SDL_FreeSurface ist deklariert als:

void SDL_FreeSurface(SDL_Surface* surface);

Als Test habe ich anhand dieser Informationen die folgende Funktion ausprobiert:

void DeleteSurface(SDL_Surface* surface)
{
    std::cout << "Deleting surface\n";
    SDL_FreeSurface(surface);
}

Beim Kompilieren mit g ++ erhalte ich jedoch den folgenden Fehler:

error: no matching function for call to 'std::shared_ptr<SDL_Surface>::shared_ptr(SDL_Surface*, <unresolved overloaded function type>)'

Ich habe mir die gnu-Dokumentation für die Implementierung von gcc std :: shared_ptr angesehen, kann aber keinen Sinn daraus machen. Was mache ich falsch?

EDIT: Ich habe da das Problem eingegrenzt, werde aber die ursprüngliche Frage oben belassen. Was ich hatte, war eine Spielklasse, die, wenn ich mich auf eine grundlegende Implementierung beschränke, ungefähr so ​​aussah:

class Game {
    public:
        /* various functions */
    private:
        void DeleteSurface(SDL_Surface* surface);
        bool CacheImages();
        std::vector<std::shared_ptr<SDL_Surface> > mCachedImages;

        /* various member variables and other functions */
}

mit der Implementierung von DeleteSurface wie oben und der Implementierung von CacheImages() wie CacheImages() :

bool CacheImages()
{
    mCachedImages.push_back(std::shared_ptr<SDL_Surface>(SDL_LoadBMP(...),DeleteSurface);
    return true;
}

bei welchem ​​spiel hab ich den fehler oben aufgelistet. Wenn ich die DeleteSurface() Funktion jedoch außerhalb der Game Klasse verschiebe, ohne sie anderweitig zu ändern, wird der Code kompiliert. Worum geht es bei der DeleteSurface der DeleteSurface Funktion in die Game Klasse, die Probleme verursacht?


std::shared_ptr<SDL_Surface>(SDL_LoadBMP(....), [=](SDL_Surface* surface)
{
    std::cout << "Deleting surface\n";
    SDL_FreeSurface(surface);
});

oder

void DeleteSurface(SDL_Surface* surface)
{
    std::cout << "Deleting surface\n";
    SDL_FreeSurface(surface);
}

std::shared_ptr<SDL_Surface>(SDL_LoadBMP(....), DeleteSurface);

BEARBEITEN:

In Ihrer aktualisierten Frage sollte DeleteSurface eine Nicht-Member-Funktion sein, andernfalls müssen Sie std::bind oder std::mem_fn oder einen anderen Member-Funktionszeigeradapter verwenden.







shared-ptr