One issue I'm having with these smart pointers is the following. Suppose I have some asset manager class like a texture manager. I want this manager to be responsible to load textures on demand when needed, and also responsible for freeing the memory. So it seems like unique_ptr makes sense. However, many other classes in the application will need a texture pointer at some time. For example, a RenderItem might need to know the textures to bind for a draw call, or a Sprite might need to know its texture.
I can't give RenderItem or Sprite a copy of unique_ptr, so this means I have to use shared_ptr. But what I don't like about shared pointer in this case is that I really only want the manager to create or delete textures. If I have shared_ptrs around, I can't be sure when all of them get destroyed--it won't necessarily be when the manager gets destoyed.
I could use shared_ptr in the manager and then weak_ptr on RenderItem and Sprite, but that feels like a workaround. I don't really want reference counting at all.
I also though about just using naked pointers in RenderItem and Sprite, with the understanding that the manager owns them. But this seems to break one of the purposes of smart pointers, which is that the code makes ownership clear rather than having to have assumptions or knowledge about the system.
What do you think is the best approach for modern C++?