20-CS-4003-001 Organization of Programming Languages Fall 2017
Virtual Functions

Lambda calculus, Type theory, Formal semantics, Program analysis

All lectures

How Virtual Functions Support Re-usable Code

    1.   vir0.cc

    It is desirable to write code which, after extensive testing and validation and maybe verification, can be placed in a library, never to be modified again. Writers of such code cannot anticipate what applications users will apply the code to and they cannot anticipate the data types users will invent. So, they write code for a base type and expect users to derive their types from that one, overriding methods of the base type. When the library is used, a library method invokes the method at the base level with the expectation that the method actually invoked is defined in the user's type. But, as this example shows, this idea is not supported in C++ without some extra modifiers to be seen below. For example, we expect that invoking f of a D object that is cast to an A object should invoke the f at the D level but it actually invokes the f at the A level (base class).
 
    2.   vir1.cc

    Some levels do not implement f. The f that is called is always at or above the level that the object is cast to.
 
    3.   vir2.cc

    All levels have implemented f, the f that is invoked is at the same level as the original object, regardless of cast.
 
    4.   vir3.cc

    The f at the bottom level is not declared virtual and the next level up does not implement f. The f that is invoked is at the lowest level at or above the original level of the invoking object regardless of cast.
 
    5.   vir4.cc

    Declaring the top level f to be virtual is enough - f is implicity virtual in all levels below the top.
 
    6.   vir5.cc

    Function f is declared virtual at the middle level only, f acts like it is not virtual above this level and like it is virtual below this level.
 
    7.   vir6.cc

    Yet another example.
 
    8.   vir7.cc
queue.cc
queue.h
    Illustration of importance of virtual methods. Abstract class Person is defined as are several concrete subclasses of Person including Vagrant, Student, and Professor. Objects of these classes are intended to be placed into lists. List services are provided by a library class called Queue which, to retain maximum generality, stores objects with void* references. Associated with each subclass are methods, declared as pure virtual in the abstract class Person, called setRank and getRank. These operate on data that is known to the subclasses but not the base class. When subclass objects are dequeued their data types are unknown because they are references only through void* pointers. To use setRank and getRank an object is cast to the Person class. Because the methods are virtual, the correct method will be invoked. Observe that since the Person class is abstract, no objects of this class can be created and enqueued.
 
    9.   vir8.cc
queue.cc
queue.h
    This is what happens if 'virtual' is removed from vir7.cc.
 
    10.   vir9.java

    This is what Java code corresponding to vir7.cc would look like. Note that there are no casts.