c++ - Typedef a shared_ptr type with a static custom deleter, similar to unique_ptr -


i have read through many questions on over custom deleter shared_ptr , unique_ptr, , difference between two. but, still haven't found clear answer question:

how can 1 best go creating type acts shared_ptr custom deleter, similar how unique_ptr has deleter part of type definition?

for unique_ptr usage, use deleter class, handles deletion of individual types (limiting 2 types, brevity):

struct sdl_deleter {                                   void operator()( sdl_surface* ptr ) { if (ptr) sdl_freesurface( ptr );}    void operator()( sdl_rwops* ptr )   { if (ptr) sdl_rwclose( ptr );}  };  using surfaceptr = std::unique_ptr<sdl_surface, sdl_deleter>; using rwopsptr = std::unique_ptr<sdl_rwops, sdl_deleter>; 

which can used like

surfaceptr surface(img_load("image.png")); 

and call sdl_freesurface upon destruction.


this fine , well. however, how 1 go achieving same shared_ptr? type defined as

template< class t > class shared_ptr; 

and way provide custom deleter through constructor. doesn't feel right user of shared_ptr wrapper needs know pointer type wrapped, , how pointer supposed deleted. best way achieve same kind of usage unique_ptr example of above.

in other words, end with:

surfaceshptr surface(img_load("image.png")); 

instead of of like

surfaceshptr surface(img_load("image.png"),                      [=](sdl_surface* ptr){sdl_freesurface(ptr);}); 

or, better

surfaceshptr surface(img_load("image.png"),                      sdl_deleter()); 

is there way this, without having create raii wrapper class (instead of typedef), adding more overhead?


if answer "this isn't possible". why not?

the other answer provided here close asked done through function returns of unique_ptr custom deleter, can implicitly converted shared_ptr.

the answer given deleter defined type trait not possible std::shared_ptr. answer suggested alternative, use function returns unique_ptr, implicitly converted shared_ptr.

since isn't part of type, possible make simple mistake, leading memory leaks. wanted avoid.

for example:

// correct usage: shared_ptr<sdl_surface> s(createsurface(img_load("image.png")));  // memory leak: shared_ptr<sdl_surface> s(img_load("image.png")); 

the concept want express having deleter part of type (which unique_ptr allows), functionality of shared_ptr. suggested solution deriving shared_ptr, , providing deleter type template argument. takes no additional memory, , works in same way unique_ptr.

template<class t, class d = std::default_delete<t>> struct shared_ptr_with_deleter : public std::shared_ptr<t> {   explicit shared_ptr_with_deleter(t* t = nullptr)       : std::shared_ptr<t>(t, d()) {}    // reset function, needs set deleter.   void reset(t* t = nullptr) { std::shared_ptr<t>::reset(t, d());  } }; 

together deleter class (thanks jonathan wakely. way cleaner macro (now removed)):

struct sdl_deleter {   void operator()(sdl_surface* p) const { if (p) sdl_freesurface(p); }   void operator()(sdl_rwops* p) const { if (p) sdl_rwclose(p); } };  using surfaceptr = std::unique_ptr<sdl_surface, sdl_deleter>; using surfaceshptr = shared_ptr_with_deleter<sdl_surface, sdl_deleter>;  using rwopsptr = std::unique_ptr<sdl_rwops, sdl_deleter>; using rwopsshptr = shared_ptr_with_deleter<sdl_rwops, sdl_deleter>; 

instances surfaceshptr members type guaranteed clean properly, same surfaceptr, wanted.

// correct usage (much harder use incorrectly now): surfaceshptr s(img_load("image.png"));  // still correct usage s.reset(img_load("other.png")); 

i'll leave while, comments, etc, without accepting answer. maybe there more dangerous caveats i've missed (having non-virtual destructor not being one, parent shared_ptr given charge of deletion).


Comments

Popular posts from this blog

python - mat is not a numerical tuple : openCV error -

c# - MSAA finds controls UI Automation doesn't -

wordpress - .htaccess: RewriteRule: bad flag delimiters -