\documentstyle[12pt]{article}
\oddsidemargin 0.25in
\topmargin -0.5in
\textheight 8.5in
\textwidth 6.25in
\newcommand{\doublespace}{
   \renewcommand{\baselinestretch}{1.5}
   \large\normalsize}
\newcommand{\singlespace}{
   \renewcommand{\baselinestretch}{1.0}
   \large\normalsize}
\newcommand{\be}{\begin{equation}}
\newcommand{\ee}{\end{equation}}

\input epsf
\begin{document}
\setcounter{page}{84}

\centerline{\large{\bf LECTURE 9}}

\centerline{\bf Virtual Functions and Polymorphism}
It has always been possible to overload a function in one class with
a member function from another class. With inheritance, you can
overload a base class member function with a member function
in a subclass as well. For example:
\begin{verbatim}
   class Student
   {
     public:
     float calcTuition();
     //...other stuff
   };
   class GraduateStudent: public Student
   {
     public:
     float calcTuition();
     //...other stuff
   };
   main()
   {
    Student s;
    GraduateStudent gs;
    s.calcTuition();          //calls Student::calcTuition()
    gs.calcTuition();         //call GraduateStudent::calcTuition()
   }
\end{verbatim}
But what if the exact class of the object can't be determined at compile
time? To demonstrate how this can occur, let's change the preceding
program in a seemingly trivial way:
\begin{verbatim}
   class Student
   {
     public:
     float calcTuition();
     //...other stuff
   };
   class GraduateStudent: public Student
   {
     public:
     float calcTuition();
     //...other stuff
   };
   void func(Student &x)
   {
    x.calcTuition();             //to which calcTuition does this refer?
   }
   main()
   {
    Student s;
    GraduateStudent gs;
    func(s);
    func(gs);
   }
\end{verbatim}
Instead of calling \verb2calcTuition()2 directly, the call is now made
through an intermediate function, \verb2func(Student &x)2. Depending
on how \verb2func(Student &x)2 is called, {\tt x} can be a {\tt Student}
or a {\tt GraduateStudent}. You would like \verb2x.calcTuition()2 to
call \verb2Student::calcTuition()2 when {\tt x} is a {\tt Student} but call
\verb2GraduateStudent::calcTuition()2 when {\tt x} is a {\tt GraduateStudent}.
Normally the compiler decides which function to call at compile time.
Even when a function is overloaded, the compiler uses the different
argument types to decide at compile time. But here the decision cannot
be made until run time, when the actual type of the object can be 
determined.

The capability to decide at run time which of several overloaded member
functions to call based on the actual type is called {\it polymorphism}.
{\it Poly} means many and {\it morph} means form (as in amorphous).
{\it Late binding} is the mechanism C++ uses to implement polymorphism.
I will tend to use the two terms interchangably. Deciding which
overloaded member functions to call at compile time is called 
{\it early binding} because that sounds like the opposite of late
binding. The default for C++ is early binding because polymorphism
adds a small amount of overhead both in terms of data storage and
code needed to perform the call.

Terminology: Another name for the actual type is the {\it run--time type}.
In the previous example, the run--time type of {\tt x} is {\tt Student}
in the call \verb2func(s)2 and the run--time type of {\tt x} is
{\tt GraduateStudent} in the call \verb2func(gs)2. The {\tt declared type}
of {\tt x} is {\tt Student} because that's what the declaration of
{\tt func} says.

To indicate polymorphism, the programmer must flag
the member function with the keyword {\it virtual}.
Virtual functions allow the programmer to declare the functions in a base
class that can be redefined in each derived class.
\begin{verbatim}
  class Base
    {
      public:
        virtual void func();
    };
  class DerivedClass: public Base
    {
      public:
        virtual void func();
    };
  void extfunc(Base &b)
    {
      b.func();
    }
  main()
    {
      Base bc;
      DerivedClass dc;
      extfunc(bc);            //calls Base::func()
      extfunc(dc);            //calls DerivedClass::func()
    }
\end{verbatim}
You need to declare the function virtual only in the base class.
The ``virtualness'' is carried down to the derived class automatically.
So we could have written:
\begin{verbatim}
  class Base
    {
      public:
        virtual void func();
    };
  class DerivedClass: public Base
    {
      public:
        void func();         //implicitly virtual
    };
\end{verbatim}
To allow a virtual function declaration to act as an interface to functions
defined in derived classes, the argument types specified for a function
in a derived class cannot differ from the argument types declared in
the base class. If the arguments don't match, there is no late
binding and the function is specified at compile time just
like any ordinary overloaded function. This is true even if the keyword
``virtual'' is used. Only very slight changes are allowed for the
return type. In particular, if the member function of the base class
returns a pointer or reference to a base class object, an overloaded
member function in a subclass may return a pointer or reference
to an object of the subclass. In other words, the following is allowed:
\begin{verbatim}
   class Base
    {
      public:
        virtual Base* func();
    };
   class DerivedClass: public Base
    {
      DerivedClass* func();
    };
\end{verbatim}

A virtual function must be defined for the
class in which it is first declared (unless it is declared to
be a pure virtual function). A virtual function can be used even if
no class is derived from its class, and a derived class that
does not need its own version of a virtual function need not provide one.
When deriving a class, simply provide an appropriate function, if it is
needed.

The great benefit of polymorphism is that one can add new derived classes
without changing the base class or the older derived classes. 
In some cases you don't even have to recompile the existing classes.
Polymorphism greatly facilitates encapsulation of the code. The details
of a function can be dealt with in the base class and its derived classes,
while the application can call the generic function which is bound at
run time. For example,
\begin{verbatim}
   class StuffYouCook{};
   class Nachos: public StuffYouCook {};
   class Oven
    {
      public:
       virtual void cook(Nachos &nachos);
       //other stuff...
    };
   class Microwave: public Oven
    {
      public:
       virtual void cook(Nachos &nachos);
       //other stuff...
    };
    Nachos makeNachos(Oven &oven)        //external function
     {
      Nachos n;
      oven.cook(n);                      //bound at run time
      return n;
     } 
\end{verbatim}
The function {\tt makeNachos} is passed an {\tt Oven} of some type.
Given that oven, it assembles all the stuff into an object {\tt n}
and then cooks them by calling \verb2oven.cook2. Exactly which
function is used, function \verb2Oven::cook2 or \verb2Microwave::cook2,
depends on the real--time type of {\tt oven}. The function
{\tt makeNachos} has no idea--and doesn't want to know--what the run--time
type of {\tt oven} is. Notice that {\tt makeNachos} doesn't need to know
the details of {\tt oven}. That's what we mean by encapsulation and
hiding the details of one part of the program from another part of the
program. Polymorphism has allowed us to greatly simplify the code since
{\tt makeNachos} doesn't have any of the {\tt oven} or {\tt Nachos}
details. The result is extensible. If a new class of {\tt oven}
comes along, e.g. {\tt ToasterOven}, with a new cook function
(\verb2ToasterOven::cook(Nachos&)2), we do not need to change
{\tt makeNachos} to incorporate the new function. Polymorphism
automatically includes the new function and calls it when necessary.

Polymorphism is the key to the power of object--oriented programming.
It's so important that languages that don't support polymorphism 
cannot advertise themselves as object--oriented languages. Languages
that support classes but not polymorphism are called object--based
languages. Ada is an example of such a language.

\centerline{\it Comments on Virtual Functions}
\begin{enumerate}
\item Static member functions cannot be declared virtual. Because static
member functions are not called with an object, there is no run--time
object to have a type.  
\item Specifying the class name in the call forces the call to bind
early. For example, the following call is to \verb2Base::func2 because
that's what the programmer indicated, even if {\tt func} is declared
virtual:
\begin{verbatim}
      class Base
    {
      public:
        virtual void func();
    };
  class DerivedClass: public Base
    {
      public:
        void func();         //implicitly virtual
    };
  void test(Base &b)
    {
      b.Base::func();        //This call is not bound late
    }
\end{verbatim}
\item A virtual function cannot be inlined. To expand a function inline,
the compiler must know which function is intended at compile time.
\item Constructors cannot be virtual because there is no completed
object to use to determine the type. At the time the constructor is
called, the memory that the object occupies is just an amorphous mass.
It's only after the constructor has finished that the object is a member of
the class in good standing. But you can define a virtual function that has the
same effect as a virtual constructor; the function
calls a constructor and returns a constructed object 
(see Stroustrup (3rd ed.), pages 424-425, for details).
\end{enumerate} 

\centerline{\bf Virtual Destructors}
The destructor should normally be declared virtual. If not,
you run the risk of improperly destructing the object, as in
the following example:
\begin{verbatim}
  class Base
  {
    public:
    ~Base();
  };
  class DerivedClass: public Base
  {
    public:
    ~DerivedClass();
  };
  void finishWithObject(Base *pHeapObject)
  {
    //work with object...
    //now return it to heap memory
    delete pHeapObject;            //this calls ~Base() no matter
                                   //what the run-time type of 
                                   //pHeapObject is
\end{verbatim}
If the pointer passed to {\tt finishWithObject} really points
to {\tt DerivedClass}, the {\tt DerivedClass} destructor is not
invoked properly. Declaring the destructor virtual solves the problem:
\begin{verbatim}
  class Base
  {
    public:
    virtual ~Base(){};             //even an empty destructor will do
  };
  class DerivedClass: public Base
  {
    public:
    ~DerivedClass();              //implicitly virtual
  };
  void finishWithObject(Base *pHeapObject)
  {
    //work with object...
    //now return it to heap memory
    delete pHeapObject;            //this calls the correct destructor
\end{verbatim}
When an object is deleted, C++ runs the object's destructor. Given that
we only have a pointer to the {\tt Base} object, which destructor
should C++ run, \verb2~Base()2 or \verb2~DerivedClass()2? The
answer depends on which kind of object the pointer points to. Such
behavior is exactly what declaring a member to be {\tt virtual}
arranges. Since one can't predict when writing a base class whether
any class eventually derived from the base class will have a
destructor member, it is safest to anticipate the possibility by
providing a virtual destructor in the public interface of the base
class. You should definitely use a virtual destructor if you use
virtual functions and pointers to the base class. In short,
the presence of a destructor in {\tt Base} ensures that every
class derived from it will be supplied with a destructor (thus getting
the size of the object right), even if the derived class doesn't
have a user--defined destructor. Even an empty destructor will do.

\centerline{\bf How Polymorphism Is Implemented}
When a class has at least one virtual function, C++ adds an additional,
hidden pointer--not one pointer per virtual function, just one
pointer if the class has any virtual functions. This pointer points to
a structure known the \verb2v_table2. The \verb2v_table2 contains
a list of pointers to all the virtual functions defined in the class.
Suppose we have the following class hierarchy:
\begin{verbatim}
   class Base
   {
     public:
       virtual void f1();
       virtual void f2();
               void nonVirtualFn();
       int d1;
   }
   class DC: public Base
   {
     public:
       virtual void f3();
       virtual void f1();
       int d2;
   };
   void func(Base &b)
   {
     b.f1();
     b.f2();
   };

   main()
   {
     Base base;
     DC subclass1;             //declare 2 subclass elements
     DC subclass2;
     
     func(base);
     func(subclass1);
   }
\end{verbatim}
The \verb2v_table2 configuration is shown in the figure. Notice that
the two {\tt DC} objects have their own \verb2v_table2 pointers,
but they share the same \verb2v_table2.

\epsfbox{lec9vtable.eps}

When {\tt func(base)} is called in {\tt main}, it is passed the object
{\tt base}. The call to {\tt b.f1} leads to \verb2Base::fn12 if you
just follow the arrows in the figure. The second time {\tt func} is 
called in {\tt main}, it is passed the object
{\tt subclass1}. If you follow the arrows, the call to {\tt b.f1}
now leads to \verb2DC::fn12. The call to {\tt b.f2} leads to 
\verb3Base::fn23 for both the object {\tt base} and the 
object {\tt subclass1}. So virtual functions introduce a little
``overhead'', but not much.

\centerline{\bf Abstract Classes and Pure Virtual Functions}
Many classes resemble class {\tt Employee} in that they are useful
as themselves and also as bases for derived classes. For such classes, the
techniques described in the previous section suffice. However, not all 
classes follow that pattern. Some classes
represent abstract concepts for which objects cannot exist. For example,
one can observe the different species of warm--blooded, baby--bearing
animals and conclude that there is a concept {\tt mammal}. You can
derive classes from mammal, such as canine, feline, and hominid. However,
it is impossible to find anywhere on earth a pure mammal, that is,
a mammal that isn't a member of some species. Mammal is an abstract
concept. Another example is the class {\tt Shape}. A
{\tt Shape} makes sense only as the base of some class derived from
it. It doesn't make sense to define functions that rotate or draw
a {\tt Shape} object, just like there are no photos of pure mammals.
So we declare the virtual functions of class {\tt Shape} to be 
{\tt pure virtual functions}. A virtual function is ``made pure''
by setting it equal to zero:
\begin{verbatim}
    class Shape{                 //abstract class
     public:
        virtual void rotate(int) = 0;      //pure virtual function
        virtual void draw() = 0;           //pure virtual function
        virtual bool is_closed() = 0;      //pure virtual function
     //...
    };
\end{verbatim}
A class with one or more pure virtual functions is an {\it abstract class},
and no objects of that abstract class can be created:
\begin{verbatim}
     Shape s;              //error: can't create object of abstract class Shape
\end{verbatim}
But it's ok to create a pointer or a reference to an abstract class
\begin{verbatim}
     func1(Shape *s);      //legal
     func2(Shape &s);      //legal
\end{verbatim}
An abstract class can be used only as an interface and as a base for
other classes. For example:
\begin{verbatim}
    class Point{ ... };

    class Circle: public Shape {
      public:
         void rotate(int){  }             //overrides Shape::rotate
         void draw();                     //overrides Shape::draw
         bool is_closed(){return true;}   //overrides Shape::is_closed

         Circle(Point p, float r);
      private:
         float radius;
         Point center;
    };
\end{verbatim}
A pure virtual function is a placeholder in the base class for the
derived class to overload with its own implementation. Without that
placeholder in the base class, there is no overloading.
A pure virtual function that is not defined in a derived class remains
a pure virtual function, so the derived class is also an abstract class.
This allows us to build implementations in stages:
\begin{verbatim}
    class Polygon: public Shape {         //abstract class
      public:
         bool is_closed(){return true;}   //overrides Shape::is_closed
         //... draw and rotate not overridden...
    };
    
    Polygon b;   //error: declaration of an object of abstract class Polygon

    class Square: public Polygon {
      public:
         void draw();                     //overrides Shape::draw
         void rotate(int);                //overrides Shape::rotate
         //....
    };

    Square s;   //fine (assume some suitable constructor)
\end{verbatim}
An important use of abstract classes is to provide an interface without
exposing any implementation details. For example, an operating system 
might hide the details of its device drivers behind an abstract class:
\begin{verbatim}
   class Device {                        //abstract class
     public:
         virtual int open(int opt) = 0;
         virtual int close(int opt) = 0;
         virtual int read(char* p, int n) = 0;
         virtual int write(const char* p, int n) = 0;
         virtual ~Device() {};          //virtual destructor
   };
\end{verbatim}
We can then specify drivers as classes derived from {\tt Device}, and
manipulate a variety of drivers through that interface.

\centerline{\bf Employee Example of Virtual Functions}
One can describe a collection of objects using an array of
base class pointers. One wants to use pointers if the objects have
different sizes. Each pointer is constructed with {\tt new}, which
sets aside the appropriate amount of memory for that particular
object. For example, suppose we want to make a data base of all 
employees. There are different kinds of employees and each type
takes up a different amount of memory. 
\begin{verbatim}
class EmployeeList : public Array<Employee *>
    {
    ...
    };

EmployeeList myDept(30);

WageEmployee *wagePtr;
SalesPerson *salePtr;
Manager *mgrPtr;

wagePtr = new WageEmployee("Bill Shapiro");
myDept[0] = wagePtr;

salePtr = new SalesPerson("John Smith");
myDept[1] = salePtr;

myDept[2] = new Manager("Mary Brown");

for(int i=0; i < myDept.numElts(); i++)
    cout << myDept[i].getName() << endl;

//Now try:

for(int i=0; i < myDept.numElts(); i++)
    cout << myDept[i].computePay() << endl;  
// error, computePay not a member of Employee
\end{verbatim}
If Employee did have a computePay, it would not be the
right one: we need a different computePay for each employee
type.

\centerline{Solution: Virtual functions}
\begin{verbatim}
class Employee                            //abstract class
    {
public:
    Employee(const char* nm);
    char *getName() const;
    virtual float computePay() const=0;   //placeholder fcn that is never called
    virtual ~Employee() {}
private:
    char name[30];
    };
\end{verbatim}
Now make sure WageEmployee, SalesPerson, Manager, each have
the line:
\begin{verbatim}
    float computePay() const;	// implicitly virtual
\end{verbatim}
Now to use it:
\begin{verbatim}
Employee *empPtr;
float salary;

empPtr = &aWorker;	
salary = empPtr->computePay(); // call WageEmployee::computePay

empPtr = &aSeller;
salary = empPtr->computePay(); // call SalesPerson::computePay

empPtr = &aBoss;
salary = empPtr->computePay(); // call Manager::computePay

//Or use our array of pointers:

for(int i=0; i < myDept.numElts(); i++)
    cout << myDept[i].computePay() << endl;  

// No problem; this works fine. 

\end{verbatim} 


\end{document}
