CS 112 - Week 14 Lecture 2 - 2022-12-01
TODAY WE WILL:
* announcements
* quick note about divide-by-zero
* adding OVERRIDING to overloading and redefining
* discussion of multiple inheritance
* prep for next class
* weird fun fact: evidentally divide by zero is NOT
defined as a C++ exception!
... instead it is a CPU signal that the OS sends to
your program signal handler routine that,
by default, terminates the program...!
====
another term! OVERRIDING, to join overloading and redefining
====
* (this is also in Savitch Ch. 15)
* redefining: for a non-virtual method, you are
making an alternate version of an inherited method
to essentially replace the inherited version
(has the same signature -- same number and types of
arguments, same return type)
* overloading: for a non-virtual method(?), you are adding
and *additional* version of that method, with different
number and/or type of arguments;
* WHEN a method IS a virtual method,
programmers often say a derived class' version of
an inherited method intended to replace the inherited
method is OVERRIDING the inherited version,
instead of redefining it.
...rather a subtle distinction!
Savitch suggest maybe this terminology is here because
the compiler DOES treat an overridden method different
than a redefined method... (the virtual overridden
method DOES have the possibility of dynamic binding)
=====
a few words on MULTIPLE inheritance!
=====
* what do we mean by this?
...we mean a derived class can have MORE than
one base class
(this is distinct from a class having, say,
ancestor classes...
Dessert -> Pie -> CustardPie is not multiple
inheritance
ParentA ParentB
^ ^
\ /
DerivedC
THIS is multiple
inheritance --
DerivedC has TWO base classes, ParentA and ParentB
* the syntax is simple:
class DerivedC: public ParentA, public ParentB
(some of the implications and complications are not
simple, but the syntax is...!)
* attempt at some examples where this be useful:
class Mammal
...
class WingedAnimal
...
class Bat: public Mammal, public WingedAnimal
...
=====
class Scanner
...
class Printer
...
class Copier: public Scanner, public Printer
...
====
a few details related to multiple inheritance
====
* the constructors of a derived class derived from
multiple base classes are called in the same
order in which they are inheritedx
(in which they appear in the class definition header)
class Bat: public Mammal, public WingedAnimal
... constructor for Mammal will be called,
then constructor for WingedAnimal will be called
* the destructors are called in REVERSE order
of the constructors
(so, first WingedAnimal's destructor,
then Mammal's destructor)
=====
ISSUES with multiple inheritance
=====
* so if both parents have a common public method,
you'll get a compiler error if you just call
that method for the derived class --
it will complain about AMBIGUITY!!
* you can get around that by explicitly specifying
which parent's you wish to call,
for each call!
DesiredParent::common_method_name
* a bigger classic problem:
the diamond problem
* can occur when you have a derived class
with multiple parents, but some of those
parents are themselves derived classes of
a common base class
class Person
....
class Student: public Person
....
class Faculty: public Person
....
class TA: public Student, public Faculty
....
==== WHAT IF, as another example:
class PoweredDevice
...
class Scanner: public PoweredDevice
...
class Printer: public PoweredDevice
...
class Copier: public Scanner, public Printer
...
* yikes -- a TA object would try to call
the Person constructor twice! -- two copies of all members
of Person;
and when that TA passes out of scope, Person's destructor
would end up being called twice;
* SOLUTION? a slightly different use of the
virtual keyword!
You can declare a class as a VIRTUAL base class
for another class by putting virtual before public
for that class:
class Faculty: virtual public Person
...
// Faculty now has Person as a virtual base class.
class Student: virtual public Person
...
// Student now has Person as a virtual base class.
=====
abstract class
=====
* a class in C++ is an ABSTRACT class if it has
at least one PURE virtual method
* what's a pure virtual method?
a pure virtual method has NO implementation.
* If a derived class is derived from an abstract base class,
it EITHER must implement every pure virtual method
OR it will also be an abstract class
* FUN FACT: a abstract class cannot be instantiated
(you can't create an instance of it). BUT it can
be used as a base class.
* SYNTAX for a pure virtual method:
in the class DECLARATION (in our case, the .h file)
virtual ret_type method_name(param_decls) = 0;
virtual double get_perimeter() = 0;
* why would we want abstract classes?
They are meant to represent general concepts
(for example, Shape or Animal etc.) for which
you don't want instances, but you WOULD like to
use as base classes for more-concrete derived
classes you do want instances of (for example, Circle or Dog, etc.)
* what about a PURE ABSTRACT class?
* A pure abstract class has ONLY abstract methods
and NO data fields and NO concrete methods
* In general, a pure abstract class is used to
define an interface and is intended to be inherited
by concrete classes.
It's a way of forcing a kind of contract between
the class designer and users of that class