First of all, I do realize this completely contradicts the purpose of a shared_ptr. I am dealing with some library code where instances of a ParticleSystem expect to have a shared_ptr passed to them during construction to set the texture used for each particle. The thing is, I've already built the rest of my program in a way where my textures have concrete ownership (if that's the right term) - the TextureCache owns all Textures. So I need a way to work with this ParticleSystem class without allowing it to delete my textures. If I were to simply create a new instance like ParticleSystem(std::shared_ptr<Texture>&myTexture)
then it would attempt to destroy the texture upon its destruction (which is an unwanted and invalid operation, since my textures aren't even created with new
).
The cleanest way I see around this problem is something like this:
I believe this solution is sound, but it still feels incredibly hackish. Is there a better way to solve my problem?
If you want to pass unmanaged pointer (that you manage by yourself) to code expecting smart pointer such as shared_ptr
, you can just disable «smart» pointer functionality by creating empty, but not-null shared_ptr
via aliasing constructor:
Texture* unmanagedPointer = ...
shared_ptr<Texture> smartPointer(shared_ptr<Texture>(), unmanagedPointer);
This solution is more efficient and shorter than custom deleter others suggested, since no control block allocation and reference counting is going on.
Some additional details can be found here:
What is the difference between an empty and a null std::shared_ptr in C++?
How to avoid big memory allocation with std::make_shared
You can create shared_ptr
with custom deleter that does nothing. This will prevent deleting textures owned by this shared_ptr
.
struct null_deleter
{
void operator()(void const *) const
{
}
};
shared_ptr<Texture> CreateTexture(Texture* myTexture)
{
shared_ptr<Texture> pTexture(myTexture, null_deleter());
return pTexture;
}
shared_ptr
allows you to supply a custom deleter. So shared_ptr
can be used for memory allocaed with malloc or whatever memory allocation scheme you're using, you could even use it to automtically unlock a mutex or close a file, but I digress. You could create a shared_ptr
with a null deleter which would not do anything when its referene count reaches 0.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With