Reputation: 5957
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?
Upvotes: 7
Views: 2647
Reputation: 167
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
Upvotes: 6
Reputation: 421
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.
Upvotes: 1
Reputation: 35716
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;
}
Upvotes: 4
Reputation: 24846
Store shared_ptr
in you Cache as Vaughn Cato suggests. In order to remove a texture from the cache when no one uses it just check if use_count
function of the shared_ptr
returns 1
, which means cache is the only owner
Upvotes: 0