CSC270 November 11 Tutorial: C++
Inheritance and Virtual Functions
One class can be built upon another. For example, in the current
simulation assignment the Event class serves as a basis for the
PersonAppearance, ElevatorArrival, and ElevatorDeparture events.
class Event {
protected:
float time; // time of event
virtual void handle_event() // function to handle the event
{}
};
An Event has a time and a function handle_event().
The word "protected" means that the components of Event are visible
to only those classes derived from Event. If it were "public", all
class could see the components, while if it were "private", no classes
(including derived classes) could see the components.
handle_event() is a "virtual function", which means that its code can
be redefined in classes that are derived from the Event class.
The PersonAppearance class is derived from the Event class. We say
that PersonAppearance "inherits" the components of the Event class.
Event is the "base class" and PersonAppearance is the "derived class".
class PersonAppearance : public Event {
public:
// the constructor
PersonAppearance( float event_time, Floor *source, Floor *dest )
time = event_time;
source_floor = source;
dest_floor = dest;
}
// a definition for the virtual function
void handle_event() {
Person *person;
person = new Person;
person->handle_initial_appearance( source_floor, dest_floor );
source_floor->schedule_next_appearance();
}
private:
Floor *source_floor;
Floor *dest_floor;
};
The syntax used above indicates that PersonAppearance is derived from
Event. The "public" keyword before "Event" indicates that public
components of Event are also public in PersonAppearance. That is,
they are visible from outside PersonAppearance. However, protected
components of Event are NOT public in PersonAppearance. We could also
use the "private" keyword, in which case public components of the base
class would be private components of the derived class and would not
be visible outside the derived class.
The constructor above shows that, when created, a PersonAppearance
event stores the event time, the floor upon which the person appears
(source) and the floor to which the person wants to go (dest). The
PersonAppearance class has all the variables of its base class
(i.e. time), in addition to its own variables (i.e. source_floor and
dest_floor).
Usefulness of virtual functions
The virtual function is very useful. We can maintain an array
containing pointers to different types of events without knowing
exactly what types they are:
Event* events[100];
Since we know that all Events have a time and a handle_event()
function, we can find the event of minimum time and `handle' it,
regardless of the actual type of the event.
min = 0;
for (i=1; i<100; i++) // find the event of minimum time
if (events[i]->time < events[min]->time)
min = i;
events[min]->handle_event(); // handle it
Note that the handle_event() function called above will be different
for the different types of Event. That is, PersonAppearance has one
version of handle_event(), ElevatorArrival (which is derived from
Event) has another version, and ElevatorDeparture (also derived from
Event) has yet another version. C++ uses a technique called "dynamic
binding" to determine, during execution, what version of the function
to execute. This is all hidden from the programmer.