#include #include using namespace std; class Person { public: Person(int s, const string & n = "") : ssn(s), name(n) { } virtual ~Person() {} const string & getName() const { return name; } int getSsn() const { return ssn; } virtual void print(ostream & out = cout) const { out << ssn << ", " << name; } private: int ssn; string name; }; ostream & operator<<(ostream & out, const Person &p) { p.print(out); return out; } class Student : public Person { public: Student(int s, const string &n="", double g=0.0) : Person(s, n), gpa(g) {} double getGpa() const { return gpa; } void print(ostream &out=cout) const { Person::print(out); out << ", " << gpa; } private: double gpa; }; class Teacher : public Person { public: Teacher(int s, const string &n="", const string &d="") : Person(s, n), department(d) {} string getDepartment() const { return department; } void print(ostream &out=cout) const { Person::print(out); out << ", " << department; } private: string department; }; int main() { Person p(987654321, "Bob"); Student s(123456789, "Jane", 4.0); Teacher t(326382700, "Richard", "CSE"); cout << "--- Print using operatop<< ---" << endl; cout << p << endl << s << endl << t << endl; cout << "--- Print using print methods ---" << endl; // If Person::print was declared to be "virtual", then // The following lines will give the same output as above. // Otherwise, they will be different. p.print(cout); cout << endl; s.print(cout); cout << endl; t.print(cout); cout << endl; cout << "--- Dynamic Cast Demo ---" << endl; Person *pp1 = &s; Person *pp2 = &t; Student *ps1 = dynamic_cast(pp1); Student *ps2 = dynamic_cast(pp2); cout << "ps1 = " << ps1 << endl << "ps2 = " << ps2 << endl; return 0; }