class Foo {
public:
  Foo() { y = new int[2];}
  ~Foo() { delete [] y; }
  Foo(const Foo& f) { 
    this->y = new int[2];
    // copy the values
    y[0] = f.y[0];
    y[1] = f.y[1];
    x[0] = f.x[0];
    x[1] = f.x[1];
  }
  Foo& operator=(const Foo& f) {
    // cleanup old data structures & reallocate (technically not
    // required for this example since the dynamically-allocated
    // memory size is fixed)
    delete [] y;
    y = new int[2];
    // copy the values
    y[0] = f.y[0];
    y[1] = f.y[1];
    x[0] = f.x[0];
    x[1] = f.x[1];
  }
private:
  int x[2];
  int *y;
};


int main() {

  Foo a; // automatically allocated
  Foo *b = new Foo(); // explicitly (dynamically) allocated
  Foo c(a); // copy constructor
  Foo d;
  d = a; // assignment operator

  //
  // do something interesting 
  //

  delete b; // explicitly deallocate the explicitly allocated memory

  // NOTE: when we leave the current scope (this function) the
  // destructor is also called for the automatically allocated memory
  // (a, c, & d)
}

