/**
 * An example of using objects in C++, focusing on constructors,
 * destructors, and various copying effects.
 *
 * Author: Zach Tomaszewski
 */
#include <iostream>
#include "Cat.hpp"

using namespace std;

void danger(Cat& cat);
void shakeItOff(Cat cat);


int main() {
  //pointer-based use
  cout << "Life of a pointer Cat: " << endl;
  Cat* kitty = new Cat("Fluffy");
  cout << "Name: " << kitty->getName() << endl;
  cout << "Lives: " << kitty->getLives() << endl;
  Cat* kitty2 = kitty;  //now 2 pointers to 1 object...
  kitty2->badLuck();
  delete(kitty);  //...so only call free one of them1
  
  cout << endl << endl;
  
  //regular use
  cout << "Creating a regular cat... " << endl;
  Cat puss("Lucky", 2);
  cout << "Name: " << puss.getName() << endl;
  cout << "Lives: " << puss.getLives() << endl;
  
  //use assignment to create a new Cat
  cout << "... and a copy (which suffers a mishap): " << endl;
  Cat feline = puss;  //performs a default struct-like copy/assignment
  feline.badLuck();  //but puss is unaffected!
  cout << "Name: " << feline.getName() << endl;
  cout << "Lives: " << feline.getLives() << endl;
  cout << endl;  

  //demo of one difference between passing by value and by reference
  cout << "Creating two more cats and subjecting each to a different danger.";
  cout << endl;
  Cat c1("George", 4);
  Cat c2("Rex", 4);
  shakeItOff(c1);
  danger(c2);
  cout << c1.getName() << ": " << c1.getLives() << "; ";
  cout << c2.getName() << ": " << c2.getLives() << endl;
  cout << endl;  
  
  //assigning one Cat to another
  c1 = c2;
  
  //now all local/automatic variables well be destroyed.
  cout << "All done." << endl;
  
  return 0;
}


/* Calls badLuck on a reference, so affects original Cat */
void danger(Cat& cat) {
  cat.badLuck();
}

/* Calls badLuck on a local copy, so original Cat is unaffected*/
void shakeItOff(Cat cat) {
  cat.badLuck();
}

