This series of problems is really about knowing and recognizing the requirements for polymorphism but presented in a more authentic format. In the "real world," it will be rare for someone to ask you to list the requirements for polymorphism. On the other hand, as a practicing computer scientist, you must be able to read and understand the behavior of computer code, which includes recognizing when polymorphism is active and when it is not.
In summary, the requirements for polymorphism:
class Parent { public: void funcA() { . . . } virtual void funcB() { . . . } void funcC() { . . . } }; class Child : public Parent { public: void funcA() { . . . } virtual void funcB() { . . . } }; int main() { Parent* P1 = new Parent; Parent* P2 = new Child; Child* C1 = new Child; Child temp; Parent P3 = temp; P1->funcA(); // (a) Parent: No upcast (Parent on both sides of the assignment operator) P1->funcB(); // (b) Parent: No upcast (Parent on both sides of the assignment operator) P1->funcC(); // (c) Parent: No upcast (Parent on both sides of the assignment operator) P2->funcA(); // (d) Parent: Not a virtual function (function determined by the pointer type) P2->funcB(); // (e) Child: All polymorphic requirements satisfied P2->funcC(); // (f) Parent: No function override (Child inherits funcC from Parent) C1->funcA(); // (g) Child: No upcast (Child on both sides of the assignment operator) C1->funcB(); // (h) Child: No upcast (Child on both sides of the assignment operator) C1->funcC(); // (i) Parent: No function override (Child inherits funcC from Parent) P3.funcA(); // (j) Parent: Not a pointer variable, so the assignment operation slices off all child features P3.funcB(); // (k) Parent: Not a pointer variable, so the assignment operation slices off all child features P3.funcC(); // (l) Parent: Not a pointer variable, so the assignment operation slices off all child features return 0; }