#include <iostream>

class Name {
  char *name;
public:
  Name(const char*);
  Name(const Name &);
  const char* get_name() const;
  ~Name();
};

// The implementation of Name is only needed 
//   to compile the program; it does not affect 
//   the implementation of Student.

Name::Name(const char* aName) {
  name = new char[strlen(aName)+1];
  strcpy(name, aName);
}

Name::Name(const Name & aName) {
  name = new char[strlen(aName.get_name())+1];
  strcpy(name, aName.get_name());
}

const char * Name::get_name() const {
  return name;
}

Name::~Name() {
  delete name;
}

// Below is the solution to Problem 2

class Student {
  const Name name;
  Name *nickname;
public:
  Student(const char*, const char*);
  ~Student();
  const Name & get_name() const;
  const Name & get_nick() const;
};

Student::Student(const char* aName, const char* aNickname=0) : name(aName) {
  if (aNickname) {
    nickname = new Name(aNickname);
  }
  else {
    nickname = 0;
  }
}

Student::~Student() {
  
  if (nickname) {
    delete nickname;
  }
}

const Name & Student::get_name() const {
  return name;
}

const Name & Student::get_nick() const {
  // should really check if nickname is NULL
  //   and if so, raise an exception. 
  return *nickname;
}


// Simple test program

int main() {
  Student joe("joe", "JJ");
  Student jane("janet", "jane");
  cout << joe.get_name().get_name() << joe.get_nick().get_name() << endl;
  cout << jane.get_name().get_name() << jane.get_nick().get_name() << endl;
}
