title: Correct object pool implementation in C++?
body: <p>I've been trying to find a way to implement an object pool in my project. I've found a few examples on the internet and most of them use std::lists and an example of it in a book; Game development patterns and best practices that also use std::list.</p>
  <p>I've been told, however, that it's kind of pointless to use lists for object pooling since returning an object back to the pool means that memory has to be allocated again.</p>
  <p>I have also seen people utilize std::stack but I assume the same issue exists.</p>
  <p>Here's the code I made for an object pool class following the book's example:</p>
  <pre><code>    /* This object has only an int data type (value).
         One method to se it and another one to print it. */
  class Object
  {
      public: 
  
          Object()
          {
              SetValue();
              std::cout &lt;&lt; &quot;Constructed/Reset.&quot; &lt;&lt; std::endl;
          }
  
              // Copy constructor
          Object( Object&amp; other )
          {
              this-&gt;mValue = other.mValue;
              std::cout &lt;&lt; &quot;Constructed.&quot; &lt;&lt; std::endl;
          }
  
          ~Object()
          {
              std::cout &lt;&lt; &quot;Destroyed.&quot; &lt;&lt; std::endl;
          }
  
          void SetValue( int val = -1 )
          {
              mValue = val;
          }
  
          void PrintValue()
          {
              std::cout &lt;&lt; this-&gt;mValue &lt;&lt; std::endl;
          }
  
      private:
          int mValue;
  
  };
  
  class Pool
  {
      public:
          Pool()
          {
              std::cout &lt;&lt; &quot;Pool created!\n&quot;;
          }
  
          ~Pool()
          {
              std::cout &lt;&lt; &quot;Pool destroyed!\n&quot;;
          }
  
          void Fill( int size )
          {
              for( int i = 0; i &lt; size; i++ )
              {
                  Object* obj = new Object();
                  pool.push_back( obj );
              }
              std::cout &lt;&lt; &quot;Objects created!&quot; &lt;&lt; &quot;\nObjects in pool: &quot;
                        &lt;&lt; pool.size() &lt;&lt; std::endl;
          }
  
          Object* AquireObject()
          {
              if( !pool.empty() )
              {
                  Object* obj = pool.back();
                  pool.pop_back();
                  
                  std::cout &lt;&lt; &quot;Object aquired!&quot;
                            &lt;&lt; &quot;\nNumber of objects in pool: &quot; &lt;&lt; pool.size() &lt;&lt; std::endl;
  
                  return obj;
              }
              else
              {
                  std::cout &lt;&lt; &quot;Object created and aquired!&quot;
                            &lt;&lt; &quot;\nNumber of objects in pool: &quot; &lt;&lt; pool.size() &lt;&lt; std::endl;
                  return new Object();
              }
          }
  
          void ReleaseObject( Object* returningObject )
          {
              returningObject-&gt;SetValue();
              pool.push_back( returningObject );
              std::cout &lt;&lt; &quot;Object returned to the pool!&quot;
                        &lt;&lt; &quot;\nNumber of objects in pool: &quot; &lt;&lt; pool.size() &lt;&lt; std::endl;
          }
  
          void Clear()
          {
              while( !pool.empty() )
              {
                  Object* obj = pool.back();
                  pool.pop_back();
                  delete obj;
              }
              std::cout &lt;&lt; &quot;Objects deleted!&quot;
                        &lt;&lt; &quot;\nNumber of objects in pool: &quot; &lt;&lt; pool.size() &lt;&lt; std::endl;
          }
  
      private:
          std::list&lt;Object*&gt; pool;
  };
  </code></pre>
  <p>I also made a slightly different version that uses unique pointers instead:</p>
  <pre><code>    /* This object has only an int data type (value).
         One method to se it and another one to print it. */
  class Object
  {
      public: 
  
          Object()
          {
              SetValue();
              std::cout &lt;&lt; &quot;Constructed/Reset.&quot; &lt;&lt; std::endl;
          }
  
              // Copy constructor
          Object( Object&amp; other )
          {
              this-&gt;mValue = other.mValue;
              std::cout &lt;&lt; &quot;Constructed.&quot; &lt;&lt; std::endl;
          }
  
          ~Object()
          {
              std::cout &lt;&lt; &quot;Destroyed.&quot; &lt;&lt; std::endl;
          }
  
          void SetValue( int val = -1 )
          {
              mValue = val;
          }
  
          void PrintValue()
          {
              std::cout &lt;&lt; this-&gt;mValue &lt;&lt; std::endl;
          }
  
      private:
          int mValue;
  
  };
  
      // Object pool using std::list
  class Pool
  {
      public:
          Pool() = default;
          ~Pool() = default;
  
              /* Fills the pool (list) with a given size using an Object class (previously defined)
                 as a reference using its copy constructor.*/
          void Fill( int size, Object* obj )
          {
              for( int i = 0; i &lt; size; i++ )
              {
                  std::unique_ptr&lt;Object&gt; object = std::make_unique&lt;Object&gt;( *obj );
                  pool.push_back( std::move( object ) );
              }
          }
  
              // Clears all items in the list.
          void PoolIsClosed()
          {
              pool.clear();
          }
  
              // Returns an instance of an object within the list.
          std::unique_ptr&lt;Object&gt; GetObject()
          {
              if( !pool.empty() )
              {
                  std::unique_ptr&lt;Object&gt; object = std::move( pool.front() );
                  pool.pop_front();
                  
                  std::cout &lt;&lt; &quot;Object retrieved.&quot; &lt;&lt; &quot;\nObjects in pool: &quot;
                            &lt;&lt; pool.size() &lt;&lt; std::endl;
                  
                  return object;
              }
              else
              {
                  /* &quot;WARNING: NOT ALL CONTROL PATHS RETURN A VALUE.&quot; */
                  std::cout &lt;&lt; &quot;Pool is empty.&quot; &lt;&lt; std::endl;
              }
          }
  
              // Returns an instance back to the object list.
          void returnToPool( std::unique_ptr&lt;Object&gt; returningObject )
          {
              pool.push_back( std::move( returningObject ) );
              
              std::cout &lt;&lt; &quot;Object returned.&quot; &lt;&lt; &quot;\nObjects in pool: &quot;
                        &lt;&lt; pool.size() &lt;&lt; std::endl;
          }
  
      private:
          std::list&lt;std::unique_ptr&lt;Object&gt;&gt; pool;
  };
  </code></pre>
  <p>I want to know if an implementation like this is really pointless and if so, is there a simple-ish way to implement a basic object pool class?</p>
  <p>I know that the boost library has its own implementation of an object pool... Has anyone of you used it before? I would love to know more about it, is it hard to use?..</p>
  <p>I also found this object pool library: <a href="https://github.com/mrDIMAS/SmartPool" rel="nofollow noreferrer">https://github.com/mrDIMAS/SmartPool</a> which looks promising and kind of easy to use but I don't know how it works under the hood, it was a bit complicated for me to understand. Any opinions about this one?</p>