Reputation: 195
Say I have a library SXY which gives me a picture from a file:
Picture * pic;
pic=get_picture("directory/file")
And I share it over multiple functions. But I want to call picture_close(pic) to dellocate it only when I am done and all these functions went out of a scope. shared_ptr already does that but if I do:
shared_ptr<Picture> pic=get_picture("file")
It won't won't compile first because the function get_picture returns a pointer to a Picture and not a shared_ptr and when it goes out of scope it won't call picture_close(pic) which is the proper way to deallocate it. Is there by any chance a custom form of a shared pointer that calls a sort of destructor only when all references to this picture went out of scope?
If I do a object and call the picture_close(pic) in the destructor of it's class it will call the destructor and deallocate the picture whenever the object is copied which is what I am having.
Upvotes: 1
Views: 891
Reputation: 66194
I think you're asking how to provide custom-deleter capabilities to a std::shared_ptr
, and then utilize that by attaching your pre-allocated point therein. The most common use of this would be some pre-existing handle-type APIs that require such workflows.
One way to do it is like the following code. I've provided mock versions of get_picture
and picture_close
, as well as a Picture
class, but hopefully you get the idea.
#include <iostream>
#include <vector>
#include <memory>
struct Picture
{
Picture() { std::cout << __PRETTY_FUNCTION__ << '\n'; }
virtual ~Picture() { std::cout << __PRETTY_FUNCTION__ << '\n'; }
void report() { std::cout << "report!\n"; }
};
Picture *get_picture()
{
return new Picture();
}
void picture_close(Picture *p)
{
std::cout << "deleting picture\n";
delete p;
}
void foo(std::vector<std::shared_ptr<Picture>> pictures)
{
for (auto& sp : pictures)
sp->report();
}
int main()
{
std::vector<std::shared_ptr<Picture>> pictures;
for (int i=0; i<5; ++i)
pictures.emplace_back(get_picture(), picture_close);
foo(pictures);
}
Output
Picture::Picture()
Picture::Picture()
Picture::Picture()
Picture::Picture()
Picture::Picture()
report!
report!
report!
report!
report!
deleting picture
virtual Picture::~Picture()
deleting picture
virtual Picture::~Picture()
deleting picture
virtual Picture::~Picture()
deleting picture
virtual Picture::~Picture()
deleting picture
virtual Picture::~Picture()
You can find out more about the various mechanisms you can create and maintain shared pointers here. Bookmark that site, btw; it's a real asset in your war chest as you're exposed to more and more of the C++ standard library.
Upvotes: 1