title: Is an isFull() function for a Dynamic Array Container Class needed?
body: <p>I'm having a bit of trouble wrapping this around my head; I used the debugger in VS to go through my code. I realized that when I call the <code>insertBack()</code> function in <code>main()</code> the elements aren't inserted since the condition <code>if (!isFull)</code> isn't met--returning false causing the insertion to not happen. I tried removing the condition and got some errors regarding my code trying to insert a number into an invalid portion of the array. While going through this, I started to ask myself is the <code>isFull()</code> function required since a dynamic array can be resized; but, how can it be full if this is the case? I looked a bit into vectors on cpprefrence and didn't find an <code>isFull()</code> member function.</p>
  
  <pre class="lang-cpp prettyprint-override"><code>#include &lt;iostream&gt;
  
  template&lt;typename T&gt;
  class container
  {
      template &lt;typename T2&gt;
      friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp; out, const container&lt;T2&gt; &amp;cobj);
      // Postcondition: contents of the container object cobj is displayed
  public:
      container();
      // Postcondition: an empty container object is created with data members arr set to NULL, n set to -1 and Capacity set to 0
      ~container();
      // Destructor; required as one of the Big-3 (or Big(5) because of the presence of a pointer data member. Default version results in 
      //    memory leak!
      // Postcondition: dynamic memory pointed to by arr has been release back to the “heap” and arr set to NULL or nullptr
      //                 In order to see the action, message "destructor called and dynamic memory released!" is displayed
      bool isEmpty() const;
      // Postcondition: returns true is nothing is stored; returns false otherwise
      bool isFull() const;
      // Postcondition: returns true if arr array is filled to capacity; returns false otherwise
      int size() const;
      // Postcondition: returns the size or the number of elements (values) currently stored in the container
      int capacity() const;
      // Postcondition: returns the current storage capacity of the container
      bool insertBack(const T&amp; val);
      // Postcondition: if container is not full, newVal is inserted at the end of the array; 
      //                otherwise, double the current capacity followed by the insertion
      bool deleteBack();
      //  Precondition: The array must not be empty
      // Postcondition: the last element stored in the array is removed! size of the container is decremented by 1, capacity unchanged
      void clear();
      // Postcondition: all elements in arr of calling container object are cleared and the dynamic memory is released back to “heap” 
  private:
      void allocate(T* &amp;temp);
      // Postcondition: if Capacity = 0, allocate a single location; otherwise the current capacity is doubled
      T *arr;
      int Capacity;   // Note: Capital 'C' as capacity is used as a function name
      int n;          // size or actual # of values currently stored in the container; n &lt;= SIZE
  };
  
  template&lt;typename T2&gt;
  std::ostream&amp; operator&lt;&lt;(std::ostream&amp; out, const container&lt;T2&gt; &amp;cobj)
  {
      std::cout &lt;&lt; "Currently it contains " &lt;&lt; cobj.size() &lt;&lt; " value(s)" &lt;&lt; std::endl
          &lt;&lt; "Container storage capacity = " &lt;&lt; cobj.capacity() &lt;&lt; std::endl
          &lt;&lt; "The contents of the container:" &lt;&lt; std::endl;
  
      if (cobj.isEmpty())
      {
          std::cout &lt;&lt; "*** Container is currently empty!" &lt;&lt; std::endl;
      }
      else
      {
          for (int i=0; i&lt;cobj.size(); ++i)
          {
              std::cout &lt;&lt; cobj.arr[i];
          }
      }
  
      return out;
  }
  
  template&lt;typename T&gt;
  container&lt;T&gt;::container()
  {
      arr = nullptr;
      Capacity = 0;
      n = 0;
  }
  
  template&lt;typename T&gt;
  container&lt;T&gt;::~container()
  {
      delete arr;
      arr = nullptr;
      std::cout &lt;&lt; "Destructor called! (this line is normally not displayed)" &lt;&lt; std::endl;
  }
  
  template&lt;typename T&gt;
  bool container&lt;T&gt;::isEmpty() const
  {
      return n==0;
  }
  
  template&lt;typename T&gt;
  bool container&lt;T&gt;::isFull() const
  {
      return n==Capacity;
  }
  
  template&lt;typename T&gt;
  int container&lt;T&gt;::capacity() const
  {
      return Capacity;
  }
  
  template&lt;typename T&gt;
  int container&lt;T&gt;::size() const
  {
      return n;
  }
  
  template&lt;typename T&gt;
  bool container&lt;T&gt;::insertBack(const T&amp; val)
  {
      if (!isFull())
      {
          n++;
          arr[n-1] = val;
          return true;
      }
      else
      {
          return false;
      }
  }
  
  template&lt;typename T&gt;
  bool container&lt;T&gt;::deleteBack()
  {
      if (!isEmpty())
      {
          n--;
          return true;
      }
      else
      {
          return false;
      }
  }
  
  template&lt;typename T&gt;
  void container&lt;T&gt;::clear()
  {
      if (!isEmpty())
      {
          n = 0;
          return true;
      }
      else
      {
          return false;
      }
  }
  
  template&lt;typename T&gt;
  void container&lt;T&gt;::allocate(T* &amp;temp)
  {
      if (Capacity==0)
      {
          temp = new T;
      }
      else
      {
          return Capacity*2;
      }
  }
  
  int main()
  {
      container&lt;int&gt; a1;
      std::cout &lt;&lt; a1 &lt;&lt; std::endl; 
      std::cout &lt;&lt; "Currently, the container object contains 0 element(s) or 0 value(s)" &lt;&lt; std::endl;
  
      std::cout &lt;&lt; "\nWe now insert 3 values at the back of the array, one at a time:" &lt;&lt; std::endl;
  
      const int num = 3;
      for (int i=0, c=0; i&lt;=num; ++i, c+=10)
      {
          a1.insertBack(c);
      }
  
      std::cout &lt;&lt; a1;
  }
  </code></pre>