**Discussion 10: Polymorphism and Virtual Functions** 10/27, 10/29 [(back to course webpage)](./mcs360_fall2020.html) # Inheritance and Protected Members Recall that: + Parent's private members don't get inherited + Parent's protected and public members get inherited + Parent's protected and public members are Child's private by default + `class Child: public Parent` would inherit public members of Parent as public members of Child # Polymorphism (look [here](https://www.cplusplus.com/doc/tutorial/polymorphism/) for a comprehensive tutorial) Polymorphism is when the same class can have two different children inheriting from it. For example, both rectangles and triangles are shapes with some height and some width property, but they have different areas. ## Example Let us look at the following code for a shape class and its children, Triangle and Rectangle: ```cpp #include class Shape { protected: double height, width; public: Shape() { height = 0; width = 0; } Shape(double h, double w) { height = h; width = w; } double area() { std::cout << "Shape is not defined, so area is not computable\n"; return -1; } void dilate(double alpha) { height *= alpha; width *= alpha; } }; class Rectangle: public Shape { public: Rectangle(double h, double w):Shape(h, w) { } double area() { return height * width; } }; class Triangle: public Shape{ public: Triangle(double h, double w):Shape(h, w) { } double area() { return 0.5 * height * width; } }; ``` If you now have a rectangle `R(10,5)` and a triangle `T(10,5)` and print `R.area()` and `T.area()`, you will get 50 and 25, respectively. ## Shape pointer pointing to both `R` and `T` Interestingly, you can have a `Shape* s` pointing to both `R` and `T` by doing `s = &R`, but when you try printing `s->area()` you would only print the Shape's area function. # Virtual Functions Virtual functions let you define functions in the class Shape that can be redefined in its children! To define `Shape::area()` as a virtual function, just declare it as `virtual double Shape::area()`. Then `s->area()` would call the area function of the children instead of the parent! # Full CPP Code with Output ```cpp #include class Shape { protected: double height, width; public: Shape() { height = 0; width = 0; } Shape(double h, double w) { height = h; width = w; } double area() { std::cout << "Shape is not defined, so area is not computable\n"; return -1; } void dilate(double alpha) { height *= alpha; width *= alpha; } }; class Rectangle: public Shape { public: Rectangle(double h, double w):Shape(h, w) { } double area() { return height * width; } }; class Triangle: public Shape{ public: Triangle(double h, double w):Shape(h, w) { } double area() { return 0.5 * height * width; } }; int main() { Rectangle R(10,5); Triangle T(10,5); std::cout << R.area() << "\n"; std::cout << T.area() << "\n"; Shape* s; s = &R; std::cout << s->area() << '\n'; s = &T; std::cout << s->area() << std::endl; return 0; } ``` ## Output with virtual keyword ``` (base) potla@EKR:~/Desktop/mcs360\$ ./d10 200 100 200 100 ``` ## Output without virtual keyword ``` (base) potla@EKR:~/Desktop/mcs360\$ ./d10 50 25 Shape is not defined, so area is not computable -1 Shape is not defined, so area is not computable -1 ```