Lecture 4

Operator overloading

You can overload most operators such as +, -, ++, --, ==, !=, += etc so that they perform special operations over classes as if they were primitive types.

When an operator is overloaded, none of its original meaning is lost. Instead, the type of objects it can be applied to is expanded. You overload an operator by creating an operator function, which defines the operations the overloaded operator will perform over the class it will work on. Operator functions can be members or non-members.

A member operator function takes this general form:

returntype class-name :: operator#(argument-list)
{
 //operations 
}
  • # - a placeholder. If you overload /, use operator/.
  • If you overload a unary operator (eg ++), the argument list should be empty.
  • If you overload a binary operator (eg +), the object on the left of + generates the call to the operator function, and the object on the right of + is an argument of the function.

Example - Stack

// header
void operator+(int i);
int operator-();
bool operator==(const iStack& z);
// overload + for push
void Stack::operator+(int i)
{
  push(i);
}

// overload -- for pop
int Stack::operator--()
{
  return pop();
}

// overload ==
bool iStack::operator==(const iStack &z)
{
  if (tos !=z.tos) return false;
  if (stack_size != z.stack_size) return false;
  
  for (int i = 0; i < tos; i++)
    if (data[i] != z.data[i]) return false;
  return true;
}
int main()
{
  Stack s(3);
  
  // push using overloaded +
  s + (-8);
  s + 21;
  s + 192;
  s + (-82);
  
  // pop using overloaded --
  cout << --s << endl;
  cout << --s << endl;
  cout << --s << endl;
  ....
  return 0;
}

Inheritance

In C++, public is used instead of extends (as in Java) to denote inheritance. The most common class inheritance uses this general form:

class derived-class-name : public base-class-name 
{
	// body of class
};

Access status: All public members of the base class become public members of the derived class. The private elements of the base class remain private to the base and are not accessible by members of the derived class.

To provide greater flexibility, in addition to public and private, C++ also has protected, to create class members that are private to their class, but can still be inherited and accessed by a derived class.

In case the base class' constructor requires parameters, the derived class' constructor uses the following form of definition that passes along arguments to base class' constructor:

derived-class-constructor(arg-list) : base-class-constructor(arg-list)
{
	// body of derived constructor
}

In the derived class, a base class member function can be redefined to include operations specific to the derived class. This is called function overriding.

Virtual functions and polymorphism

A virtual function is a member function that is declared within a base class and redefined by a dervied class.

To create a virtual function, precede the function's declaration in the base class with the keyword virtual. A pure virtual function without definition in the base class can be declared as follows:

virtual return-type function-anem(arguments) = 0;

When a base class pointer points to a derived object that contains a virtual function, C++ calls the version of the function associated with the derived object pointed to by rhe pointer.

The virtual function declared in the base class defines the interface to that function. Each redefinition in a derived class implements a specific operation for that derived class. The different operations can be accessed by using a common interface - the base class pointer, pointing to the different derived objects.

Default function arguments

C++ allows a function to assign a parameter to a default value whne no arument corresponding to that parameter is specified in the call to that function.