[ fromfile: inheritance-intro.xml id: inheritanceclientcode1 ]
GradStudent
is a
Student, in the sense that a GradStudent object can be used wherever a Student object can be used.
The client code shown in Example 6.5 creates some instances and performs operations on a GradStudent or an Undergrad instance directly and also indirectly, through pointers.
Example 6.5. src/derivation/qmono/student-test.cpp
#include <QTextStream> #include "student.h" static QTextStream cout(stdout, QIODevice::WriteOnly); void graduate(Student* student) { cout << "\nThe following " << student->getClassName() << " has graduated\n " << student->toString() << "\n"; } int main() { Undergrad us("Frodo", 5562, "Ring Theory", 4); GradStudent gs("Bilbo", 3029, "History", 6, GradStudent::fellowship); cout << "Here is the data for the two students:\n"; cout << gs.toString() << endl; cout << us.toString() << endl; cout << "\nHere is what happens when they graduate:\n"; graduate(&us); graduate(&gs); return 0; }
To build this application we use qmake and make as follows:
src/derivation/qmono> qmake -project src/derivation/qmono> qmake src/derivation/qmono> make
We then can run it like this:
src/derivation/qmono> ./qmono Here is the data for the two students: [Student] [22] name: Bilbo Id: 3029 Year: gradual student Major: History [Support: fellowship ] [Student] name: Frodo Id: 5562 Year: senior Major: Ring Theory Here is what happens when they graduate: The following Student has graduated [Student] name: Frodo Id: 5562 Year: senior Major: Ring Theory The following Student has graduated [Student] name: Bilbo Id: 3029 Year: gradual student Major: History src/derivation/qmono>
Calling student->toString() from the function graduate() invokes Student::toString() regardless of what kind of object student points to.
If the object is, in fact, a GradStudent, then there should be a mention of the fellowship in the graduation message.
In addition, we should be seeing “[GradStudent]“ in the toString() messages, and we are not.
It would be more appropriate to use runtime binding for indirect function calls to determine which toString() is appropriate for each object.
Because of its C roots, C++ has a compiler that attempts to bind function invocations at compile time, for performance reasons.
With inheritance and base class pointers, the compiler can have no way of knowing what type of object it is operating on.
In the absence of runtime checking, an inappropriate function can be called.
C++ requires the use of a special key word to enable runtime binding on function calls via pointers and references.
The keyword is virtual, and it enables polymorphism, which is explained in the next section.
| Generated: $Date: 2009-09-08 12:15:32 -0400 (Tue, 08 Sep 2009) $ | © 2009 Alan Ezust and Paul Ezust. |