title: C++11 Smart Pointer Semantics
body: <p>I've been working with pointers for a few years now, but I only very recently decided to transition over to C++11's smart pointers (namely unique, shared, and weak). I've done a fair bit of research on them and these are the conclusions that I've drawn:</p>
  
  <ol>
  <li>Unique pointers are great. They manage their own memory and are as lightweight as raw pointers. Prefer unique_ptr over raw pointers as much as possible.</li>
  <li>Shared pointers are complicated. They have significant overhead due to reference counting. Pass them by const reference or regret the error of your ways. They're not evil, but should be used sparingly.</li>
  <li>Shared pointers should own objects; use weak pointers when ownership is not required. Locking a weak_ptr has equivalent overhead to the shared_ptr copy constructor.</li>
  <li>Continue to ignore the existence of auto_ptr, which is now deprecated anyhow.</li>
  </ol>
  
  <p>So with these tenets in mind, I set off to revise my code base to utilize our new shiny smart pointers, fully intending to clear to board of as many raw pointers as possible. I've become confused, however, as to how best take advantage of the C++11 smart pointers.</p>
  
  <p>Let's assume, for instance, that we were designing a simple game. We decide that it is optimal to load a fictional Texture data type into a TextureManager class. These textures are complex and so it is not feasible to pass them around by value. Moreover, let us assume that game objects need specific textures depending on their object type (i.e. car, boat, etc).</p>
  
  <p>Prior, I would have loaded the textures into a vector (or other container like unordered_map) and stored pointers to these textures within each respective game object, such that they could refer to them when they needed to be rendered. Let's assume the textures are guaranteed to outlive their pointers.</p>
  
  <p>My question, then, is how to best utilize smart pointers in this situation. I see few options:</p>
  
  <ol>
  <li><p>Store the textures directly in a container, then construct a unique_ptr in each game object.</p>
  
  <pre><code>class TextureManager {
    public:
      const Texture&amp; texture(const std::string&amp; key) const
          { return textures_.at(key); }
    private:
      std::unordered_map&lt;std::string, Texture&gt; textures_;
  };
  class GameObject {
    public:
      void set_texture(const Texture&amp; texture)
          { texture_ = std::unique_ptr&lt;Texture&gt;(new Texture(texture)); }
    private:
      std::unique_ptr&lt;Texture&gt; texture_;
  };
  </code></pre>
  
  <p>My understanding of this, however, is that a new texture would be copy-constructed from the passed reference, which would then be owned by the unique_ptr. This strikes me as highly undesirable, since I would have as many copies of the texture as game objects that use it -- defeating the point of pointers (no pun intended).</p></li>
  <li><p>Store not the textures directly, but their shared pointers in a container. Use make_shared to initialize the shared pointers. Construct weak pointers in the game objects.</p>
  
  <pre><code>class TextureManager {
    public:
      const std::shared_ptr&lt;Texture&gt;&amp; texture(const std::string&amp; key) const
          { return textures_.at(key); }
    private:
      std::unordered_map&lt;std::string, std::shared_ptr&lt;Texture&gt;&gt; textures_;
  };
  class GameObject {
    public:
      void set_texture(const std::shared_ptr&lt;Texture&gt;&amp; texture)
          { texture_ = texture; }
    private:
      std::weak_ptr&lt;Texture&gt; texture_;
  };
  </code></pre>
  
  <p>Unlike the unique_ptr case, I won't have to copy-construct the textures themselves, but rendering the game objects is expensive since I would have to lock the weak_ptr each time (as complex as copy-constructing a new shared_ptr).</p></li>
  </ol>
  
  <p>So to summarize, my understanding is such: if I were to use unique pointers, I would have to copy-construct the textures; alternatively, if I were to use shared and weak pointers, I would have to essentially copy-construct the shared pointers each time a game object is to be drawn.</p>
  
  <p>I understand that smart pointers are inherently going to be more complex than raw pointers and so I'm bound to have to take a loss somewhere, but both of these costs seem higher than perhaps they should be.</p>
  
  <p>Could anybody point me in the correct direction?</p>
  
  <p>Sorry for the long read, and thanks for your time!</p>