Comp 2673, Spring 2002
May 1, lecture notes

Reading assignment: Chapter 10 of Deitel and Deitel Virtual Functions and Polymorphism - why we need them - If you have a base class, and you have multiple derived classes, it's natural to have a list of objects of the derived classes. These objects are of different types, but all of types derived from the same base class. If we want to keep them all in one list, then we have to refer to them with base-class pointers. - Examples: base class is Shape, derived classes are Square, Circle, etc. Your list will be a list of Shapes base class is Employee, derived classes are Salaried and Hourly Your list will be a list of Employees base class is BankAccount, derived classes are SavingAccount, CheckingAccount, MoneyMarket, etc. Your list will be a list of BankAccounts - We already learned how things work if you have a version of a member function in the base class and then an overridden version in your derived class - if you're referring to the object as a base-class pointer then the base-class version is called, and if you're referring to the object as a derived class pointer, then the derived-class version is called. - Say you have a few derived classes and all have a different overridden version of a certain member function. If you store a bunch of these different types of objects in a list using base-class pointers, and then call that member function for each pointer in the list, then you get the base-class version! Often this is *not* what you want! - Virtual functions and Polymorphism gives you a way to solve this problem. Virtual Functions and Polymorphism - how to use them - Instead of defining your member function of the base class and derived class in the ordinary way, you define the function as "virtual": class Shape { ... virtual void display() const; ... }; class Square: public Shape { ... virtual void display() const; }; - As before, you implement all versions of the function in the base class and derived class(es) - Now the compiler figures out which one to call. If you have a base class pointer that points to an object of the derived class, the derived class version gets called automatically. - Notice that figuring out which version to call has to happen at run time, since the type of the object is unknown at compile time. So the compiler actually has to put code into your program that figures out which version of the function to call. "Dynamic binding" is the technical term meaning figuring-out-which-version-to-call-at-run-time - Now that we have dynamic binding, we can make a list of pointers to base-class object, and for the functions that we made "virtual", they'll be treated as pointers to the appropriate derived-class objects instead of base-class objects. This is known as "polymorphism", which means "many shapes". A single type of pointer (base-class pointers) can be used to deal with objects that are of multiple types, of many shapes. - If you want to provide a member function to all derived classes, but it doesn't make sense to put one in the base class, then make it a "pure" virtual function in the base class, as in: virtual void display() const = 0; An example: employee.h