Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems using member function as custom deleter with std::shared_ptr

I'm trying to work out how to use std::shared_ptr with a custom deleter. Specifically, I'm using it with SDL_Surface as:

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

which compiles and runs fine. However, I would like to try out my own deleter and cannot work out how to do so. The documentation for SDL_FreeSurface is found here:

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

in which I find the SDL_FreeSurface is declared as:

void SDL_FreeSurface(SDL_Surface* surface); 

As a test, and going by that information, I tried the following function:

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

However, compiling with g++ gives me the following error:

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

I have looked at the gnu documentation for the gcc std::shared_ptr implementation but cannot make much sense of it. What am I doing wrong?

EDIT: I've since narrowed down the problem, but will leave the original question above. What I had was a Game class which, if I strip it down to a basic implementation, was something like:

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 */ } 

with the implementation of DeleteSurface as above, and the implementation of CacheImages() as:

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

which game me the error I listed above. However, if I move the DeleteSurface() function outside the Game class without otherwise altering it, the code compiles. What is it about including the DeleteSurface function in the Game class that is causing problems?

like image 889
Wheels2050 Avatar asked Sep 09 '12 16:09

Wheels2050


People also ask

What is the best way to delete an object managed by shared_ptr?

If shared_ptr::unique returns true, then calling shared_ptr::reset will delete the managed object. However, if shared_ptr::unique returns false, it means there are more than one shared_ptr s sharing ownership of that object.

Why is shared_ptr unique deprecated?

this function is deprecated as of C++17 because use_count is only an approximation in multi-threaded environment.

What does shared_ptr get () do?

std::shared_ptr::getReturns the stored pointer. The stored pointer points to the object the shared_ptr object dereferences to, which is generally the same as its owned pointer.

What happens when you move a shared_ptr?

By moving the shared_ptr instead of copying it, we "steal" the atomic reference count and we nullify the other shared_ptr . "stealing" the reference count is not atomic, and it is hundred times faster than copying the shared_ptr (and causing atomic reference increment or decrement).


1 Answers

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

or

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

EDIT:

Seeing your updated question, DeleteSurface should be a non-member function, otherwise you need to use std::bind or std::mem_fn or some other member function pointer adapter.

like image 101
ronag Avatar answered Sep 21 '22 01:09

ronag