0

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.

1
  • 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. Commented Jan 22, 2015 at 17:18

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

5 Comments

Yes, the custom deleter should be handy for exactly that.
If shaders remove themselves from pool during destruction then there are no need for special deleters.
@ÖöTiib yes this is a working option but in my opinion, making shaders aware of the cache is a somewhat sloppy design. At least there are some benefits in keeping them separated.
@NickZavaritsky OP describes factory method from where "clients" can request shared shaders. I would make that method and the pool as static members of shader to keep its public interface small and clear. I'm unsure what about such design is sloppy.
@ÖöTiib my idea was that shader object should have the single responsibility of being a shader, making it responsible for the cache goes against SOLID principles. Sorry there is nothing sloppy in your design, please excuse me. I suggest we conclude this discussion now)
1

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 Comment

My wrong inference was because I read too quickly and misinterpreted what *this meant in a weak_ptr (I stupidly thought it would be the raw pointer owned by weak_ptr) and didn't spot that shared_ptr had a constructor accepting weak_ptr &.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.