Object Pool


#include 
#include 
#include 

using namespace std;

// typical use case is these objects are "expensive" to create.
class Swimmer
{
public:
  Swimmer() : bInUse(false){}
  bool bInUse; // only used for bounded pool
};

class ObjectPool
{
public:

  Swimmer* GetSwimmer()
  {
    if ( pool.size() > 0 )
      {
return pool.front();
      }
    else
      return new Swimmer();
  }

  void ReleaseSwimmer(Swimmer* aSwimmer)
  {
    pool.push_back(aSwimmer);
  }
  
private:
  vector pool;
};

// Alternate bounded pool
class BoundedObjectPool
{
public:

  Swimmer* GetSwimmer()
  {
    cout << "bounded pool get swimmer called\n";
    for ( vector::iterator iter = pool.begin(); iter != pool.end(); iter ++ )
      {
	    if ( !(*iter)->bInUse )
	      {
	        (*iter)->bInUse = true;
	        return (*iter);
	    }

      }
    
    if ( pool.size() < iPoolBound )
      {
		       Swimmer* temp = new Swimmer();
		       temp->bInUse = true;
	      pool.push_back(temp);
	      return temp;
      }

      return nullptr;
  }

  void ReleaseSwimmer(Swimmer* aSwimmer)
  {
    for ( vector::iterator iter = pool.begin(); iter != pool.end(); iter++ )
      {
		if ( (*iter) == aSwimmer)
		  (*iter)->bInUse = false;
      }
  }
  
private:
  vector pool;
  static const int iPoolBound = 5;
};


int main()
{
  cout << "Class:main, Method:main \n";

  ObjectPool anObjectPool;
  
  Swimmer* aSwimmer =  anObjectPool.GetSwimmer();

  // do something with the swimmer
  anObjectPool.ReleaseSwimmer(aSwimmer);

  // Alternate Bounded Pool
  BoundedObjectPool bop;

  for ( int i = 0; i < 7; i++ )
    {
      Swimmer* phelps = bop.GetSwimmer();
      if ( phelps == nullptr )
		       cout << "The pool is empty\n";
    }
}