C++: Polymorphism ( 多态 )
● Meaning “many forms”, polymorphism in OO terminology means a single statement in code that might do different things depending on the context in which it is executed.
○ In this case, rpt[i]->Display() is a polymorphic call (when Display() is a virtual function).
○ Depending on what kind of object we send in at runtime, that line of code can either Report’s Display() method, GradeReport’s Display() method, or OnlineGradeReport’s Display() method.
● One of the great advantages from polymorphism is that old (existing) code can can call new (being developed) code without modification.
○ If we created another class in the Report hierarchy (as a subclass of Report or of any subclass of Report), then we can write a new display() method for it, and ShowReport() will call the new Display() method without modfication.
1 #include <iostream>
2 #include <string>
3 using namespace std;
4
5 #define DEBUGBUILD 0
6 #define DEBUG if (DEBUGBUILD) cout
7
8 class Date{
9 private:
10 int day;
11 int month;
12 int year;
13 public:
14 Date() { DEBUG << "Date: default ctor" << endl; }
15 Date(int m, int d, int y) {
16 DEBUG << "Date: 3 int ctor" << endl;
17 day=d;
18 month=m;
19 year=y;
20 }
21 void Display(void) { cout << month << "/" << day << "/" << year << endl; }
22 }; // end class Date
23
24 class Time {
25 private:
26 int hour;
27 int minute;
28 int second;
29 public:
30 Time() { DEBUG << "Time: default ctor" << endl; }
31 Time(int h, int m, int s) {
32 DEBUG << "Time: 3 int ctor" << endl;
33 hour=h;
34 minute=m;
35 second=s;
36 }
37 void Display() { cout << hour << ":" << minute << ":" << second << endl; }
38 };
39
40 class Report {
41 private:
42 Date repDate;
43 Time repTime;
44 string repDesc;
45 public:
46 Report() : repDate(1,1,1970), repTime(0,0,0), repDesc("") {
47 DEBUG << "Report: default ctor" << endl;
48 repDesc = "";
49 }
50 Report(Date d, Time t, string desc) : repDate(d), repTime(t){
51 DEBUG << "Report: date time string ctor" << endl;
52 repDesc = desc;
53 }
54 virtual void Display() {
55 cout << "Date: ";
56 repDate.Display();
57 cout << "Time: ";
58 repTime.Display();
59 cout << "Description: ";
60 DisplayDesc();
61 }
62 void DisplayDesc() { cout << repDesc << endl; }
63 }; // end class Report
64
65 class GradeReport : public Report {
66 private:
67 int StudentID;
68 int CourseID;
69 public:
70 GradeReport() : StudentID(0), CourseID(0)
71 { DEBUG << "GradeReport: default ctor" << endl; }
72
73 GradeReport(Date d, Time t, string desc, int sid, int cid) :
74 Report(d, t, desc), StudentID(sid), CourseID(cid)
75 { DEBUG << "GradeReport: 5 parameters ctor" << endl; }
76
77 GradeReport(const GradeReport& gr) :
78 Report(gr), StudentID(gr.StudentID), CourseID(gr.CourseID)
79 { DEBUG << "GradeReport: Copy ctor" << endl; }
80
81 ~GradeReport() { DEBUG << "GradeReport: dtor" << endl; }
82
83 virtual void Display() {
84 DisplayID();
85 cout << "Course ID: " << CourseID << endl;
86 Report::Display();
87 }
88
89 void DisplayID() { cout << "Student ID: " << StudentID << endl; }
90 }; // end class GradeReport
91
92 class OnlineGradeReport : public GradeReport {
93 public:
94 enum ReportStatus {LOGGED, INFORMED, CONFIRMED};
95 private:
96 string program;
97 string deptDesc;
98 ReportStatus repStatus;
99 public:
100 OnlineGradeReport() : program(""), deptDesc(""), repStatus(LOGGED)
101 { DEBUG << "OnlineGradeReport: default ctor" << endl; }
102
103 OnlineGradeReport(Date d, Time t, string desc, int sid, int cid, string pro, string dept,
104 ReportStatus s) :
105 GradeReport(d, t, desc, sid, cid), program(pro), deptDesc(dept), repStatus(s)
106 { DEBUG << "OnlineGradeReport: 8 parameters ctor" << endl; }
107
108 OnlineGradeReport(const OnlineGradeReport& or) :
109 GradeReport(or), program(or.program), deptDesc(or.deptDesc), repStatus(or.repStatus)
110 { DEBUG << "OnlineGradeReport: Copy ctor" << endl; }
111
112 ~OnlineGradeReport() { DEBUG << "OnlineGradeReport: dtor" << endl; }
113 virtual void Display() {
114 DisplayStatus();
115 cout << "Program: " << program << endl;
116 cout << "Department: " << deptDesc << endl;
117 GradeReport::Display();
118 }
119 void DisplayStatus() {
120 switch(repStatus)
121 {
122 case LOGGED:
123 cout << "The grade is logged by the professor." << endl;
124 break;
125 case INFORMED:
126 cout << "The Records Office has informed the student of the grade." <<
127 endl;
128 break;
129 case CONFIRMED:
130 cout << "The student has confirmed receiving the grade report." << endl;
131 break;
132 } // end switch
133 } // end fun
134 }; // end class
135
136 void main() {
137 Date today(6, 4, 2011);
138 Time t(8, 0, 0);
139 GradeReport gradeA(today, t, "CS360", 1234, 100);
140
141 Date today2(7, 4, 2011);
142 Time t2(18, 0, 0);
143 Report status(today2, t2, "July Report");
144
145 Date today3(8, 4, 2011);
146 Time t3(26, 5, 0);
147 OnlineGradeReport or = OnlineGradeReport(today3, t3, "CS350", 1234, 100, "MSCS",
148 "Computer Science", OnlineGradeReport::ReportStatus::CONFIRMED);
149
150 Report *rpt[3];
151 rpt[0] = &gradeA;
152 rpt[1] = &status;
153 rpt[2] = ∨
154
155 for(int i = 0; i < 3; i++)
156 {
157 rpt[i]->Display();
158 cout << endl;
159 }
160 }