#include <algorithm>
#include <iostream>

class arreglo_dinamico {
   int cap, tam;
   int* p;

public:
   arreglo_dinamico( ) {
      cap = 1;
      tam = 0;
      p = new int[1];
   }

   arreglo_dinamico(const arreglo_dinamico& v) {   // constructor por copia (a quien le vamos a copiar su valor la podemos pasar como const)
      std::cout << "constructor por copia\n";
      cap = v.tam;
      tam = v.tam;
      p = new int[cap];
      for (int i = 0; i < tam; ++i) {
         p[i] = v.p[i];
      }
   }

   ~arreglo_dinamico( ) {
      std::cout << "destructor\n";
      delete[] p;
   }

   void operator=(const arreglo_dinamico& v) {     // asignación por copia (a quien le vamos a copiar su valor la podemos pasar como const)
      if (p == v.p) {
         return;
      }

      delete[] p;
      cap = v.tam;
      tam = v.tam;
      p = new int[cap];
      for (int i = 0; i < tam; ++i) {
         p[i] = v.p[i];
      }
   }

   int size( ) const {                       // función miembro const: no necesita modificar el objeto
      return tam;
   }

   int& operator[](int i) {                  // acceso a un elemento del arreglo con posibilidades de modificación
      return p[i];
   }

   const int& operator[](int i) const {      // acceso a un elemento del arreglo en modo de sólo lectura
      return p[i];
   }

   void agrega(int v) {
      if (tam == cap) {
         int* q = new int[2 * cap];
         for (int i = 0; i < tam; ++i) {
            q[i] = p[i];
         }
         delete[] p;
         p = q;
         cap *= 2;
      }

      p[tam] = v;
      tam += 1;
   }

   void quita_ultimo( ) {
      tam -= 1;
   }
};

void imprime(const arreglo_dinamico& a) {       // ver el original para no hacer la copia; usar const para prometer que no lo modificaremos
   for (int i = 0; i < a.size( ); ++i) {
      std::cout << a[i] << " ";
   }
   std::cout << "\n";
}

int main( ) {
   arreglo_dinamico a;
   a.agrega(1);
   a.agrega(2);
   a.agrega(3);
   imprime(a);                                  // no se hace una copia
   std::cout << "fin de main\n";
}


