#include #include "person.h" #include "student.h" #include using namespace std; ostream & operator<< (ostream & out, const Person & p) { p.print(out); return out; } void printVirtual() { Student s(222, "Sally Jones", 4.0 ); s.print(); cout << endl << endl; // What is printed? cout << "Experiment 1: Create Person reference pointing to Student object" << endl;; Person & person_ref = s; person_ref.print(); cout << endl << endl; // What is printed? cout << "Experiment 2: Pass a Student to function expecting Person" << endl;; operator<<(cout, s); cout << endl << endl; // cout << s << endl; } // Use call-by-value void slicing(Person p) { p.print(); cout << endl; } void downcasting() { Person* personPtr = new Person(888, "Anne"); // Downcast person to a student Student* studentPtr = (Student*)personPtr; // What is the gpa? cout << "Gpa: " << studentPtr->getGpa() << endl; // A safer way of downcasting //studentPtr = dynamic_cast(personPtr); if(studentPtr == NULL) cout << "studentPtr is NULL!" << endl; } void simple() { // When using objects (i.e. not pointers or references) there is no real // way to exploit inheritance Person p(999, "Jane Smith"); p.print(); cout << endl; Student s(000, "Joey Smith", 3.9); s.print(); cout << endl; } int main() { // simple(); // printVirtual(); // Student s(999, "Billy Robot", 1.3); // slicing(s); // downcasting(); }