## 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.

### Operator Functions

• 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.
`long 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?  (meaningless)
`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 also to define a != operator.
`bool operator!=(Time a, Time b){  return a.seconds_from(b) != 0; // return !(a == b)}`
• You may also find it useful to define a < operator.
`bool operator<(Time a, Time b){  return a.seconds_from(b) < 0; // return a - b}`

### Input and Output

• 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 type Time&.

• It is easy to go overboard operators! But 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[0], i is 1 */double b = s[++j]; /* b is s[1], 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.

### Operator Members

• 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==(Time a, Time b); /* a == b means operator==(a,b) */`
• The same operator as a member function.
`bool Time::operator==(Time b) const /* a == b means a.operator==(b) */{  return seconds_from(b) == 0;}`
• Also note that the != operator uses the == operator. Each member function has a special parameter variable, called this, which is a pointer to the implicit parameter.
`bool Time::operator!=(Time b) const{ return !(*this == b); /* calls operator==(b) */}`
• If the operator is unary, then the member function has no explicit parameter
`Time Time::operator++() /* prefix operator */{ *this = *this + 1; /* calls operator+(1) */  return *this;}`
• Note the parameter in the postfix version of the ++ operator.
`Time Time::operator++(int dummy) /* postfix operator */{  Time t = *this;    *this = *this + 1; /* calls operator+(1) */   return t;}`

## Automatic Memory Management

• For this discussion, we will use a modification of the Department class that was introduced earlier (department.cpp).
`class Department {   ...private:   string name;   Employee* receptionist;};Department::Department(string n, Employee e){  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.

### Automatic Memory Management (Destructors)

• 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

`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("Quality Control", Employee("Tester, Tina", 50000));Department dept("Shipping", Employee("Hacker, Harry", 35000));`
• Suppose we assign one department to the other (memberwise copy).
`dept = qc;`
• This assignment causes a memory leak! (See following picture).
• 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 old 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" (for example v[0] = v[i] when i = 0)
• A return by reference is required to handle chaining of assignments, such as.
`z = y = x; // equivalent to z = (y = x) and z = y.operator=(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.

### Automatic Memory Management (Copy Constructor)

• 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 assignment operator will try to delete the receptionist causing an error.
`Department dept = qc; // not assignment operator!`
• 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 (memberwise copy).
• 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!

## Automatic Memory Management (department.cpp)

• 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.