Homework 12: Dynamic Dispatch and Polymorphism
Due: 5/18 2pm
Name & Perm #:
Homework buddy (leave blank if you worked alone):
Reading: PS 15.3
1. (10 pts)
In the lectures, I mentioned dynamic dispatch is a form of polymorphism, and that some object-oriented programming resources mistakenly conflate the two.
(4 pts) What is dynamic dispatch? Why is it "dynamic"? Explain briefly.
(4 pts) What is the purpose of polymorphism? How does it differ from dynamic dispatch? Polymorphism is more general than dynamic dispatch, explain how it is more general.
2. \( \)
On page 868 in PS, in Display 15.12, line 17, there is a use of the
overloaded operator <
on two objects, one of type Sale
and another
of type DiscountSale
. The definition of that operator appears on lines
25 - 28 of Display 15.10 on p. 866. On line 27, there is an invocation
of first.bill()
and an invocation of second.bill()
.
(2 pts) For
first.bill()
in the case of the invocation in Display 15.12 line 17, where is the definition of the member function bill() that is invoked? Give the name of the class whosebill()
function is invoked.(2 pts) For
second.bill()
in the case of the invocation in Display 15.12 line 17, where is the definition of the member function bill() that is invoked? Give the name of the class whosebill()
function is invoked.(2 pts) The
bill()
member function is special in that the exact definition of the function used depends on what type of object it is invoked on–whether it is an instance ofSale
orDiscountSale
, which may not be known until run-time. What is the C++ keyword that is used in the definition ofbill()
that signals this so called dynamic dispatch of the member function?
3. (8 pts)
Assume we have a base class (e.g. Person) and derived class
(e.g. Student), and there is some function such as toString()
that is
defined in both the base class and the dervied class.
For example, suppose that:
- for Person,
toString
returns the person's name, e.g.Chris Gaucho
- for Student,
toString
returns the person's name and their perm number in parentheses. e.g.Chris Gaucho (1234567)
.
We say that toString()
is overridding in the derived class. However, in PS
(15.3), Savitch makes a distinction between the two cases, one that is properly
called overriding and another that should really be called
redefinition. Most of the cases we've seen so far are really just
redefinition. What is different, according to Savitch, in the case where this
should be called overriding? Hint: the override
keyword covered in class is
relevant here.
4. \( \)
Given the following class definitions (you may assume all necessary libraries have already been included):
class A { public: ~A() { cout << "A::~A()" << endl; } void f1() { cout << "A::f1()" << endl; } virtual void f2() { cout << "A::f2()" << endl; } }; class B : public A { public: virtual ~B() { cout << "B::~B()" << endl; } virtual void f1() { cout << "B::f1()" << endl; } void f2() { cout << "B::f2()" << endl; } virtual void f3() = 0; }; class C : public B { public: ~C() { cout << "C::~C()" << endl; } void f1() { cout << "C::f1()" << endl; } virtual void f3() { cout << "C::f3()" << endl; } };
(6 pts) What will the output be if we ran the following code (be sure to include destructors' output):
void f1() { C c1; A a1 = c1; a1.f1(); a1.f2(); } int main() { f1(); }
(6 pts) What will the output be if we ran the following code (be sure to include destructors' output):
void f2() { B* b1 = new C(); b1->f1(); b1->f2(); b1->f3(); delete b1; } int main() { f2(); }