0
votes

I want to have a pool of shared objects whose class name is Shader. I want a "client" to be able to request a Shader with certain parameters from the pool manager, and if there's one already in the pool the manager will return a pointer or reference to it, otherwise it creates a new Shader and adds it to the pool before returning its reference. Easy enough so far.

However, I also want the Shaders to be automatically deleted when all the clients have finished with them. Is this possible by implementing the pool as a container of std::weak_ptr and returning std::shared_ptr to the clients? Ie if I call weak_ptr::lock() multiple times on the same object are the shared_ptrs it returns linked to each other correctly, or does it return independent shared_ptrs leading to undefined behaviour? cpprefrence.com implies the latter, but they don't explictly point out the danger of that, and it seems to me that an opportunity was missed to make weak_ptr considerably more useful.

2
How would your container know if its element got invalidated? You would need to perform some garbage collecting if you don't plan on using reference counting. - luk32

2 Answers

1
votes

Is this possible by implementing the pool as a container of std::weak_ptr and returning std::shared_ptr to the clients?

Yes.

Ie if I call weak_ptr::lock() multiple times on the same object are the shared_ptrs it returns linked to each other correctly, or does it return independent shared_ptrs leading to undefined behaviour?

weak_ptr::lock() returns shared_ptr linked to other shared_ptrs to that object or empty shared_ptr when there are no other shared_ptrs (IOW weak_ptr::expired() is true).

cpprefrence.com implies the latter, but they don't explictly point out the danger of that, and it seems to me that an opportunity was missed to make weak_ptr considerably more useful.

I can not understand how you read that implication.

1
votes

Calling weak_ptr::lock() multiple times is ok, the returned shared_ptr is configured properly, i.e. all shared_ptr-s having the common pointee are sharing the reference counter.

Note that lock() returns non-null pointer iff there is at least one shared_ptr pointing to the object. If there was none then the object would have been already destroyed. Hence lock() absolutely must implement sharing right otherwise it would break on every call.

Finally shared_ptr supports custom deleter functions, they may be useful to remove stale entries from the cache.