## Chapter Goals

• To learn how to automatically manage dynamic memory

• Many classes use operators such as ++, * and ==.
• Giving a new meaning to an operator is called operator overloading.
• You can overload an operator by defining a function whose name is operator followed by the operator symbol.
• For example, you can define the difference between two Time objects as the number of seconds between them.
`int operator-(Time a, Time b){ return a.seconds_from(b);}`
• The operator- function is a nonmember function with two parameters.
• Now you can use the - operator instead of calling seconds_from.
`Time now;Time morning(9, 0, 0);long seconds_elapsed = now - morning;`
• The last statement is equivalent to
`long seconds_elapsed = operator-(now, morning);`

`return_type operatoroperator_symbol(parameters){   statements}`
 Example: `int operator-(Time a, Time b){ return a.seconds_from(b)}` Purpose: Supply the implementation of an overloaded operator.
• Does it make sense to add two times?
`some_return_type operator+(Time a, Time b);`
• A Time objects represent a point in time, not a duration: what does 3 P.M. + 3 P.M. mean? It does not make any sense to add two points in time!
• It does make sense to add a number of seconds to a Time object, resulting in a new Time object.
`Time operator+(Time a, int sec){  Time r = a;   r.add_seconds(sec);   return r;}`
• For example
`Time now;Time later = now + 60; /* 60 seconds later */`
• A commonly overloaded operator is the == operator, to compare two values.
`bool operator==(Time a, Time b){  return a.seconds_from(b) == 0;}`
• For completeness, it is a good idea to also define a != operator.
`bool operator!=(Time a, Time b){  return a.seconds_from(b) != 0;}`
• You may also find it useful to define a < operator.
`bool operator<(Time a, Time b){  return a.seconds_from(b) < 0;}`
• For many classes, you want to print the object with the familiar << notation.
• The output operator takes a parameter of type ostream& (reference, because printing modifies the stream) and the object to be printed.
`ostream& operator<<(ostream& out, Time a){  out << a.get_hours() << ":";   if (a.get_minutes() < 10) out << "0";   out << a.get_minutes() << ":";   if (a.get_seconds() < 10) out << "0";   out << a.get_seconds();   return out;}`
• The << operator returns the out stream to enable chaining of the << operator.
`cout << now << "\n";`
really means
`(cout << now) << "\n";`
that is
`operator<<(cout, now) << "\n";`
• The call to operator<<(cout, now) returns cout, then cout << "\n" prints a new line.
• You can also overload the input operator to read in other types of objects.
`istream& operator>>(istream& in, Time& a){  int hours;   int minutes;   int seconds;   in >> hours >> minutes >> seconds;   a = Time(hours, minutes, seconds);   return in;}`
• Note that the >> operator returns the input stream just like the << operator.
• Unlike the << operator, the >> operator must have a parameter of Time&.
• It is easy to go overboard overloading operators! Using inappropriate operators can make programs more difficult to read.
• Does it make sense to overload *, / or % for Time objects?

• There are actually two forms of the ++ and -- operators.
• A prefix form:
`++x;`
• A postfix form:
`x++;`
• Recall that ++x evaluates to x after the increment, and x++ evaluates to x before the increment.
`int i = 0;int j = 0;vector<double> s(10);double a = s[i++]; /* a is s, i is 1 */double b = s[++j]; /* b is s, j is 1 */`
• In order for the compiler to distinguish between the two versions, the operators must have two different parameter lists.
`void operator++(Time& a) /* prefix operator */. . .void operator++(Time& a, int dummy) /* postfix operator */`
• The int dummy parameter is not used inside the function, it merely serves to differentiate the two operator++ functions.
• Some operators must access the internals of the class and must be member functions.
• Member functions use the implicit parameter as the left operand.
• A non member operator:
`bool operator==(Iterator a, Iterator b)`
• The same operator as a member function:
`bool Iterator::operator==(Iterator b) const`
• If the operator is unary, then the member function has no explicit parameter
`string Iterator::operator*() const`
• Actual implementation of the operators is somewhat anticlimactic.
`string Iterator::operator*() const{  assert(position != NULL);   return position->data;}bool Iterator::operator==(Iterator b) const{  return position == b.position;}`
• Note the parameter in the postfix version of the ++ operator.
`void Iterator::operator++(int dummy) const{  assert(position != NULL);   return = position->next;}`
• Also note that the != operator uses the == operator.
`bool Iterator::operator!=(Iterator b) const{  return !(*this == b); // calls operator ==}`

## Automatic Memory Management

• For this discussion, we will use a modification of the Department class that was introduced earlier.
`class Department {   ...private:   string name;   Employee* receptionist;};Department::Department(string n, Employee){  name = n;   receptionist = new Employee(e.get_name(), e.get_salary());}/* second constructor */Department::Department(string n){  name = n;   receptionist = NULL;}`
• A Department object contains a pointer to an Employee object.
• When the Department object is destroyed (goes out of scope, for example) the Employee object is leaked.
• In C++, you can define a destructor, a function that is called when an object is about to go out of scope.
• The destructor for the Department class should delete the receptionist pointer.
`Department::~Department(){  delete receptionist;}`
• Note that calling delete on a NULL pointer is safe, so you don't need a special case for that situation.

## Syntax 17.2: Destructor Definition

Syntax 17.2 : Destructor Definition

`Class_name::~Class_name(){   statements}`
 Example: `Department::~Department(){ delete receptionist;}` Purpose: Supply the implementation of a destructor that is invoked whenever and object goes out of scope.
• The destructor is automatically invoked (not called directly).
`{  Department dept;   ...} // dept.~Department() automatically invoked here...Department* p = new Department(...);...delete p; // p->~Department() automatically invoked here`
• A class can only have one destructor with no parameters.
• You should always supply a destructor when some amount of clean up is required when an object goes out of scope.
• Recycling dynamic memory (as shown here).
• Close a file.
• Relinquish some other resource.
• Consider the following declarations.
`Department qc("Qualitiy Control", Employee("Tester, Tina", 50000));Department dept("Shipping", Employee("Hacker, Harry", 35000));`
• Suppose we assign one department to the other.
`dept = qc;`
• This assignment causes a memory leak! (See following slide).
• When one object goes out of scope (and the other doesn't) the Employee is destroyed, causing a dangling pointer. • The remedy is to overload the operator= to make the assignment safe by deleting the only Employee object, and making a copy of the new Employee object.
`Department& Department::operator=(const Department& b){  if (this != & b)   {  name = b.name;      delete receptionist;      if (b.receptionist == NULL)         receptionist == NULL;      else         receptionist = new Employee(b.receptionist->get_name(),            b.receptionist->get_salary());    }    return *this;}`
• Unlike most other operators, the operator= must be a member function.
• Special care must be taken to avoid a destructive "self-assignment."
• A return by reference is required to handle chaining of assignments, such as.
`z = y = x;`
• You should always overload the = operator if your class has data fields that are pointers, and a simple copy of objects leads to dangerous shared pointers.
• The purpose of operator= is to set an existing object equal to another object.
• Use of = for construction is not always appropriate.
• Example: Here, the pointer dept.receptionist is set to a random value. The operator will try to delete the receptionist causing an error.
`Department dept = qc;`
• The copy constructor defines how to construct an object of a class as a copy of another object of the same class.
`Department dept(qc)`
• If you don't define a copy constructor, then the compiler provides a version that simply copies the corresponding data fields of the existing object.
• This version of the copy constructor is still inappropriate, leading to the same kind of errors as the default version of the assignment operator.
• Here is a valid copy constructor for the Department class.
`Department::Department(const Department& b){  name = b.name;   if (b.receptionist == NULL)      receptionist = NULL;   else      receptionist = new Employee(b.receptionist->get_name(),         b.receptionist->get_salary());}`
• The parameter must be const reference because pass by value invokes the copy constructor!
• The assignment operator, copy constructor, and destructor are collectively called the "big three."
• You must implement all three for any class that manages heap memory.
• Each function has the following logic.
• Destructor:
Free all dynamic memory that the object manages.
• Copy Constructor:
Initialize the object as a copy of the explicit parameter object.
• Assignment Operator:
Check whether this == &b. If so do nothing.
Free the dynamic memory of the object that is no longer needed.
Set the object as a copy of the explicit parameter object.
Return
*this.